Beispiel #1
0
        private static async Task CreateArchiveAsync(string sourcePath, string headerFilePath, string dataFilePath)
        {
            if (!Directory.Exists(sourcePath))
            {
                throw new Exception($"Directory doesn't exist \"{sourcePath}\".");
            }

            var filePaths = GetFilesRelative(sourcePath);

            MS2File[] files = new MS2File[filePaths.Length];
            var       tasks = new Task[filePaths.Length];

            for (uint i = 0; i < filePaths.Length; i++)
            {
                uint ic = i;
                tasks[i] = Task.Run(() =>
                {
                    var(filePath, relativePath) = filePaths[ic];

                    files[ic] = MS2File.Create(ic + 1u, relativePath, CompressionType.Zlib, CryptoMode, filePath);
                });
            }

            await Task.WhenAll(tasks).ConfigureAwait(false);

            await MS2Archive.Save(CryptoMode, files, headerFilePath, dataFilePath, RunMode.Async2).ConfigureAwait(false);
        }
        private static void UpdateRandomFilesFromArchive(MS2Archive archive)
        {
            const int    minFilesForRandom       = 10;
            const string folderForAddingName     = "FilesForAddingToArchive";
            string       folderToArchive         = Path.Combine(@"..\TestData", folderForAddingName);
            string       folderToArchiveFullPath = Path.GetFullPath(folderToArchive) + @"\";

            string[] filesToArchive = Directory.GetFiles(folderToArchive, "*.*", SearchOption.AllDirectories).Select(p => Path.GetFullPath(p)).ToArray();
            Assert.IsTrue(filesToArchive.Length > minFilesForRandom, $"you need at least {minFilesForRandom} files in the adding archive folder for this test");

            uint             count         = (uint)Random.Next(minFilesForRandom, filesToArchive.Length);
            HashSet <string> distinctFiles = new HashSet <string>();
            uint             i             = 0;

            while (i < count)
            {
                if (distinctFiles.Add(filesToArchive[Random.Next(0, filesToArchive.Length)]))
                {
                    i++;
                }
            }
            string[] files = distinctFiles.ToArray();
            Assert.AreEqual(files.Length, (int)count);
            for (i = 0; i < count; i++)
            {
                string  file         = files[i];
                int     index        = Random.Next(0, archive.Files.Count);
                MS2File previousFile = archive.Files[index];

                archive.Files[index] = MS2File.CreateUpdate(previousFile, file);
            }
        }
Beispiel #3
0
        public void Dispose_EncapsulatedMemoryMappedFile_DoesNotThrowObjectDisposedException()
        {
            var expectedBytes = new byte[] { 0x30, 0x60 };
            var archiveMock   = new Mock <IMS2Archive>(MockBehavior.Strict);
            var mappedFile    = MemoryMappedFile.CreateNew(nameof(Dispose_EncapsulatedMemoryMappedFile_DoesNotThrowObjectDisposedException), expectedBytes.Length, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);
            var info          = new MS2FileInfo("1", "testfile");
            var header        = new MS2FileHeader(expectedBytes.Length, 1, 0);
            var file          = new MS2File(archiveMock.Object, mappedFile, info, header, false);

            file.Dispose();

            mappedFile.CreateViewAccessor();
        }
Beispiel #4
0
        public void Dispose_EncapsulatedStream_ThrowsObjectDisposedException()
        {
            var expectedBytes = new byte[] { 0x30, 0x60 };
            var archiveMock   = new Mock <IMS2Archive>(MockBehavior.Strict);
            var stream        = new MemoryStream(expectedBytes);
            var info          = new MS2FileInfo("1", "testfile");
            var header        = new MS2FileHeader(expectedBytes.Length, 1, 0);
            var file          = new MS2File(archiveMock.Object, stream, info, header, false);

            file.Dispose();

            stream.ReadByte();
        }
Beispiel #5
0
        public async Task Dispose_GetStreamForArchivingAsync_ThrowsObjectDisposedException()
        {
            var expectedBytes = new byte[] { 0x30, 0x60 };
            var archiveMock   = new Mock <IMS2Archive>(MockBehavior.Strict);
            var stream        = new MemoryStream(expectedBytes);
            var info          = new MS2FileInfo("1", "testfile");
            var header        = new MS2FileHeader(expectedBytes.Length, 1, 0);
            var file          = new MS2File(archiveMock.Object, stream, info, header, false);

            file.Dispose();

            await file.GetStreamForArchivingAsync();
        }
Beispiel #6
0
        private static async Task ExtractArchiveSync(string headerFile, string dataFile, string destinationPath)
        {
            using (MS2Archive archive = await MS2Archive.Load(headerFile, dataFile).ConfigureAwait(false))
            {
                List <MS2File> files = archive.Files;

                for (int i = 0; i < files.Count; i++)
                {
                    MS2File file = files[i];
                    Logger.Info($"Extracting file \"{file.Name}\", \"{FileEx.FormatStorage(file.Header.Size)}\". ({file.Header.Id}/{files.Count})");
                    await ExtractFileAsync(destinationPath, file).ConfigureAwait(false);
                }
            }
        }
Beispiel #7
0
        private static async Task ExportArchiveAsync(string headerFile, string dataFile, string destinationFilePath)
        {
            using (var swExport = new StreamWriter(destinationFilePath))
                using (MS2Archive archive = await MS2Archive.Load(headerFile, dataFile).ConfigureAwait(false))
                {
                    List <MS2File> files = archive.Files;

                    for (int i = 0; i < files.Count; i++)
                    {
                        MS2File file = files[i];
                        Logger.Info($"Exporting file \"{file.Name}\". ({file.Header.Id}/{files.Count})");
                        await ExportFileAsync(swExport, file).ConfigureAwait(false);
                    }
                }
        }
Beispiel #8
0
        public async Task GetStreamAsync_StreamEncryptedFalseAndCompressionZlib_EqualsInput()
        {
            string input    = "testdatainputcompressed";
            string expected = input;

            using MemoryStream inputStream = StringToStream(input);
            var archiveMock = CreateArchiveMock();
            var infoMock    = CreateFileInfoMock("1", "testfile");
            var sizeMock    = CreateSizeMock(input.Length, input.Length, input.Length);
            var headerMock  = CreateFileHeaderMock(sizeMock, 1, 0, CompressionType.Zlib);
            var file        = new MS2File(archiveMock.Object, inputStream, infoMock.Object, headerMock.Object, false);

            var actualStream = await file.GetStreamAsync();

            string actual = await StreamToString(actualStream);

            Assert.AreEqual(expected, actual);
        }
Beispiel #9
0
        public async Task GetStreamAsync_StreamEncryptedTrueAndCompressionZlib_EqualsExpected()
        {
            string        input              = "testdatainputencryptedcompressed";
            string        expected           = "testdataexpected";
            MS2CryptoMode cryptoMode         = (MS2CryptoMode)12345;
            var           sizeMock           = CreateSizeMock(10, 20, 30);
            IMS2ArchiveCryptoRepository repo = new FakeCryptoRepository(cryptoMode, EncodingTest, expected, input, sizeMock.Object);

            using MemoryStream inputStream = StringToStream(input);
            var archiveMock = CreateArchiveMock(repo);
            var infoMock    = CreateFileInfoMock("1", "testfile");
            var headerMock  = CreateFileHeaderMock(sizeMock, 1, 0, CompressionType.Zlib);
            var file        = new MS2File(archiveMock.Object, inputStream, infoMock.Object, headerMock.Object, true);

            var actualStream = await file.GetStreamAsync();

            string actual = await StreamToString(actualStream);

            Assert.AreEqual(expected, actual);
        }
Beispiel #10
0
        private static Task ExportFileAsync(StreamWriter swExport, MS2File file)
        {
            string fileName = file.Name;

            if (String.IsNullOrWhiteSpace(fileName))
            {
                Logger.Warning($"File number \"{file.Id}\" has no name and will be ignored.");
                return(Task.CompletedTask);
            }

            uint            id     = file.Header.Id;
            CompressionType typeId = file.CompressionType;

            FileTypes.AddOrUpdate(Path.GetExtension(fileName), new HashSet <string>()
            {
                typeId.ToString()
            }, (_, v) => { v.Add(typeId.ToString()); return(v); });

            string rootDirectory = PathEx.GetRootDirectory(fileName);

            if (!String.IsNullOrEmpty(rootDirectory))
            {
                if (String.IsNullOrEmpty(file.InfoHeader.RootFolderId))
                {
                    Logger.Warning($"Root folder id is empty but it has a root folder ({rootDirectory})!");
                }

                RootFolderIds.AddOrUpdate(rootDirectory, new HashSet <string>()
                {
                    file.InfoHeader.RootFolderId
                }, (_, v) => { v.Add(file.InfoHeader.RootFolderId); return(v); });
            }

            int    propCount = file.InfoHeader.Properties.Count;
            string info      = String.Join(",", file.InfoHeader.Properties);

            return(swExport.WriteLineAsync($"{id:d6} - Type:{typeId}; Properties:{propCount}; Info={info}"));
        }
Beispiel #11
0
        public async Task GetStreamForArchivingAsync_StreamEncryptedTrueAndCompressionNone_EqualsInput()
        {
            string        input              = "testdatainput";
            string        expected           = input;
            MS2CryptoMode cryptoMode         = (MS2CryptoMode)12345;
            var           sizeMock           = CreateSizeMock(10, 10, 10);
            var           expectedSize       = sizeMock.Object;
            IMS2ArchiveCryptoRepository repo = new FakeCryptoRepository(cryptoMode, EncodingTest, input, expected, sizeMock.Object);

            using MemoryStream inputStream = StringToStream(input);
            var archiveMock = CreateArchiveMock(repo);
            var infoMock    = CreateFileInfoMock("1", "testfile");
            var headerMock  = CreateFileHeaderMock(sizeMock, 1, 0, CompressionType.None);
            var file        = new MS2File(archiveMock.Object, inputStream, infoMock.Object, headerMock.Object, true);

            var(actualStream, actualSize) = await file.GetStreamForArchivingAsync();

            string actual = await StreamToString(actualStream);

            Assert.AreEqual(expected, actual);
            Assert.AreEqual(expectedSize.EncodedSize, actualSize.EncodedSize);
            Assert.AreEqual(expectedSize.CompressedSize, actualSize.CompressedSize);
            Assert.AreEqual(expectedSize.Size, actualSize.Size);
        }
Beispiel #12
0
        private static async Task ExtractFileAsync(string destinationPath, MS2File file)
        {
            if (String.IsNullOrWhiteSpace(file.Name))
            {
                Logger.Warning($"File number \"{file.Id}\", \"{FileEx.FormatStorage(file.Header.Size)}\" has no name and will be ignored.");
                return;
            }

            string fileDestinationPath = Path.Combine(destinationPath, file.Name);

            (Stream stream, bool shouldDispose) = await file.GetDecryptedStreamAsync().ConfigureAwait(false);

            try
            {
                await stream.CopyToAsync(fileDestinationPath).ConfigureAwait(false);
            }
            finally
            {
                if (shouldDispose)
                {
                    stream.Dispose();
                }
            }
        }
        public async Task TestCreateConsistencyMS2F()
        {
            const string archiveName             = "PrecomputedTerrain";
            const string folderToArchive         = @"C:\Users\Miyu\Desktop\ReleaseOutput\Resource\" + archiveName;
            string       folderToArchiveFullPath = Path.GetFullPath(folderToArchive) + @"\";

            string[] filesToArchive = Directory.GetFiles(folderToArchive, "*.*", SearchOption.AllDirectories).Select(p => Path.GetFullPath(p)).ToArray();

            const string  headerFilePath    = @"..\TestData\PrecomputedTerrain.m2h";
            const string  dataFilePath      = @"..\TestData\PrecomputedTerrain.m2d";
            MS2CryptoMode archiveCryptoMode = MS2CryptoMode.MS2F;

            MS2File[] files = new MS2File[filesToArchive.Length];
            for (int i = 0; i < filesToArchive.Length; i++)
            {
                string file = filesToArchive[i];

                files[i] = MS2File.Create((uint)i + 1u, file.Remove(folderToArchiveFullPath), CompressionType.Zlib, archiveCryptoMode, file);
            }

            const string testArchiveName    = "FromExtractedMS2F";
            const string headerTestFileName = testArchiveName + ".m2h";
            const string dataTestFileName   = testArchiveName + ".m2d";

            try
            {
                await MS2Archive.Save(archiveCryptoMode, files, headerTestFileName, dataTestFileName, RunMode.Async2).ConfigureAwait(false);

                Assert.IsTrue(File.Exists(headerTestFileName));
                Assert.IsTrue(File.Exists(dataTestFileName));

                using (MS2Archive archive = await MS2Archive.Load(headerFilePath, dataFilePath).ConfigureAwait(false))
                {
                    Dictionary <uint, MS2File> mappedFiles = archive.Files.Zip(files, (o, s) => (o, s))
                                                             .ToDictionary(f => f.o.Id, f => files.Where(sf => sf.Name == f.o.Name).First());
                    Assert.AreEqual(archive.CryptoMode, archiveCryptoMode);
                    Assert.AreEqual(archive.Files.Count, filesToArchive.Length);
                    //Assert.AreEqual(archive.Name, ArchiveName);

                    Task[] tasks = new Task[filesToArchive.Length];

                    for (int i = 0; i < filesToArchive.Length; i++)
                    {
                        int ic = i;
                        tasks[ic] = Task.Run(async() =>
                        {
                            MS2File file      = archive.Files[ic];
                            MS2File savedFile = mappedFiles[file.Id];
                            var(savedStream, savedShouldDispose) = await savedFile.GetDecryptedStreamAsync().ConfigureAwait(false);
                            try
                            {
                                Assert.AreEqual(file.Id, (uint)ic + 1);
                                Assert.AreEqual(file.CompressionType, CompressionType.Zlib);
                                Assert.IsTrue(file.IsZlibCompressed);
                                Assert.AreEqual(file.Name, savedFile.Name);
                                Assert.AreEqual(file.Header.CompressionType, file.CompressionType);
                                Assert.AreEqual(file.Header.Size, (uint)savedStream.Length);

                                (Stream stream, bool shouldDispose) = await file.GetDecryptedStreamAsync().ConfigureAwait(false);
                                try
                                {
                                    byte[] savedBytes     = new byte[savedStream.Length];
                                    byte[] originalBytes  = new byte[stream.Length];
                                    int savedReadBytes    = await savedStream.ReadAsync(savedBytes, 0, savedBytes.Length).ConfigureAwait(false);
                                    int originalReadBytes = await stream.ReadAsync(originalBytes, 0, originalBytes.Length).ConfigureAwait(false);
                                    Assert.AreEqual(originalReadBytes, savedReadBytes);

                                    CollectionAssert.AreEqual(originalBytes, savedBytes);
                                }
                                finally
                                {
                                    if (shouldDispose)
                                    {
                                        stream.Dispose();
                                    }
                                }
                            }
                            finally
                            {
                                if (savedShouldDispose)
                                {
                                    savedStream.Dispose();
                                }
                            }
                        });
                    }

                    await Task.WhenAll(tasks).ConfigureAwait(false);
                }
            }
            finally
            {
                File.Delete(headerTestFileName);
                File.Delete(dataTestFileName);
            }
        }
        public async Task TestCreateCompletelyNewNS2F()
        {
            const string folderForArchiving      = "TestFolderForArchiving";
            string       folderToArchive         = Path.Combine(@"..\TestData", folderForArchiving);
            string       folderToArchiveFullPath = Path.GetFullPath(folderToArchive) + @"\";

            string[] filesToArchive = Directory.GetFiles(folderToArchive, "*.*", SearchOption.AllDirectories).Select(p => Path.GetFullPath(p)).ToArray();

            MS2CryptoMode cryptoMode = MS2CryptoMode.NS2F;

            MS2File[] files = new MS2File[filesToArchive.Length];
            for (int i = 0; i < filesToArchive.Length; i++)
            {
                string file = filesToArchive[i];

                files[i] = MS2File.Create((uint)i + 1u, file.Remove(folderToArchiveFullPath), CompressionType.Zlib, cryptoMode, file);
            }

            const string testArchiveName    = "TestArchiveNS2F";
            const string headerTestFileName = testArchiveName + ".m2h";
            const string dataTestFileName   = testArchiveName + ".m2d";

            try
            {
                await MS2Archive.Save(cryptoMode, files, headerTestFileName, dataTestFileName, RunMode.Async2).ConfigureAwait(false);

                Assert.IsTrue(File.Exists(headerTestFileName));
                Assert.IsTrue(File.Exists(dataTestFileName));

                using (MS2Archive archive = await MS2Archive.Load(headerTestFileName, dataTestFileName).ConfigureAwait(false))
                {
                    Assert.AreEqual(archive.CryptoMode, cryptoMode);
                    Assert.AreEqual(archive.Files.Count, filesToArchive.Length);
                    //Assert.AreEqual(archive.Name, ArchiveFolder);

                    for (int i = 0; i < filesToArchive.Length; i++)
                    {
                        FileStream fsFile = File.OpenRead(filesToArchive[i]);
                        MS2File    file   = archive.Files[i];
                        Assert.AreEqual(file.Id, (uint)i + 1);
                        Assert.AreEqual(file.CompressionType, CompressionType.Zlib);
                        Assert.IsTrue(file.IsZlibCompressed);
                        Assert.AreEqual(file.Name, filesToArchive[i].Remove(folderToArchiveFullPath));
                        Assert.AreEqual(file.Header.CompressionType, file.CompressionType);
                        Assert.AreEqual(file.Header.Size, (uint)fsFile.Length);

                        (Stream stream, bool shouldDispose) = await file.GetDecryptedStreamAsync().ConfigureAwait(false);

                        try
                        {
                            byte[] originalBytes     = new byte[fsFile.Length];
                            byte[] savedBytes        = new byte[stream.Length];
                            int    originalReadBytes = await fsFile.ReadAsync(originalBytes, 0, originalBytes.Length).ConfigureAwait(false);

                            int savedReadBytes = await stream.ReadAsync(savedBytes, 0, savedBytes.Length).ConfigureAwait(false);

                            Assert.AreEqual(originalReadBytes, savedReadBytes);

                            CollectionAssert.AreEqual(originalBytes, savedBytes);
                        }
                        finally
                        {
                            if (shouldDispose)
                            {
                                stream.Dispose();
                            }
                        }
                    }
                }
            }
            finally
            {
                File.Delete(headerTestFileName);
                File.Delete(dataTestFileName);
            }
        }