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(); }
public static MpqFile GetEnvironmentFile(this Map map, Encoding?encoding = null) { using var memoryStream = new MemoryStream(); using var writer = new BinaryWriter(memoryStream, encoding ?? _defaultEncoding, true); writer.Write(map.Environment); writer.Flush(); return(MpqFile.New(memoryStream, MapEnvironment.FileName)); }
public static MpqFile GetInfoFile(this Campaign campaign, Encoding?encoding = null) { using var memoryStream = new MemoryStream(); using var writer = new BinaryWriter(memoryStream, encoding ?? _defaultEncoding, true); writer.Write(campaign.Info); writer.Flush(); return(MpqFile.New(memoryStream, CampaignInfo.FileName)); }
public static MpqFile GetScriptFile(this Map map, Encoding?encoding = null) { using var memoryStream = new MemoryStream(); using var writer = new StreamWriter(memoryStream, encoding ?? _defaultEncoding, leaveOpen: true); writer.Write(map.Script); writer.Flush(); return(MpqFile.New(memoryStream, map.Info.ScriptLanguage == ScriptLanguage.Lua ? "war3map.lua" : "war3map.j")); }
public void AddAll(string folder) { if (mpqArchiveBuilder != null) { foreach ((var fileName, var _, var stream) in EnumerateFiles(folder)) { mpqArchiveBuilder.RemoveFile(fileName); mpqArchiveBuilder.AddFile(MpqFile.New(stream, fileName)); } } }
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); }
public static MpqFile?GetCustomTextTriggersFile(this Map map, Encoding?encoding = null) { if (map.CustomTextTriggers is null) { return(null); } using var memoryStream = new MemoryStream(); using var writer = new BinaryWriter(memoryStream, encoding ?? _defaultEncoding, true); writer.Write(map.CustomTextTriggers, encoding ?? _defaultEncoding); writer.Flush(); return(MpqFile.New(memoryStream, MapCustomTextTriggers.FileName)); }
public static MpqFile?GetUpgradeObjectDataFile(this Map map, Encoding?encoding = null) { if (map.UpgradeObjectData is null) { return(null); } using var memoryStream = new MemoryStream(); using var writer = new BinaryWriter(memoryStream, encoding ?? _defaultEncoding, true); writer.Write(map.UpgradeObjectData); writer.Flush(); return(MpqFile.New(memoryStream, MapUpgradeObjectData.FileName)); }
public static MpqFile?GetPreviewIconsFile(this Map map, Encoding?encoding = null) { if (map.PreviewIcons is null) { return(null); } using var memoryStream = new MemoryStream(); using var writer = new BinaryWriter(memoryStream, encoding ?? _defaultEncoding, true); writer.Write(map.PreviewIcons); writer.Flush(); return(MpqFile.New(memoryStream, MapPreviewIcons.FileName)); }
public static MpqFile?GetItemObjectDataFile(this Campaign campaign, Encoding?encoding = null) { if (campaign.ItemObjectData is null) { return(null); } using var memoryStream = new MemoryStream(); using var writer = new BinaryWriter(memoryStream, encoding ?? _defaultEncoding, true); writer.Write(campaign.ItemObjectData); writer.Flush(); return(MpqFile.New(memoryStream, CampaignItemObjectData.FileName)); }
public static MpqFile?GetTriggerStringsFile(this Map map, Encoding?encoding = null) { if (map.TriggerStrings is null) { return(null); } using var memoryStream = new MemoryStream(); using var writer = new StreamWriter(memoryStream, encoding ?? _defaultEncoding, leaveOpen: true); writer.WriteTriggerStrings(map.TriggerStrings); writer.Flush(); return(MpqFile.New(memoryStream, MapTriggerStrings.FileName)); }
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); }
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); }
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); }
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); }
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); }
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); }
public static void TranspileAndSave(string inputFile, string outputFile, string?commonJPath, string?blizzardJPath, ScriptLanguage targetLanguage, BackgroundWorker?worker) { var targetFileName = targetLanguage switch { ScriptLanguage.Jass => "war3map.j", ScriptLanguage.Lua => "war3map.lua", _ => throw new InvalidEnumArgumentException(nameof(targetLanguage), (int)targetLanguage, typeof(ScriptLanguage)), }; using var mapArchive = MpqArchive.Open(inputFile, true); var map = Map.Open(mapArchive); var sourceLanguage = map.Info.ScriptLanguage; var mpqArchiveBuilder = new MpqArchiveBuilder(mapArchive); using var mapInfoStream = new MemoryStream(); using var mapInfoWriter = new BinaryWriter(mapInfoStream); var mapInfo = map.Info; mapInfo.ScriptLanguage = targetLanguage; if (mapInfo.FormatVersion < MapInfoFormatVersion.Lua) { mapInfo.FormatVersion = MapInfoFormatVersion.Lua; if (mapInfo.GameVersion is null) { mapInfo.GameVersion = GamePatchVersionProvider.GetGameVersion(GamePatch.v1_31_1); } } mapInfoWriter.Write(mapInfo); mapInfoStream.Position = 0; mpqArchiveBuilder.AddFile(MpqFile.New(mapInfoStream, MapInfo.FileName)); if (sourceLanguage == ScriptLanguage.Jass) { if (targetLanguage != ScriptLanguage.Lua) { throw new NotSupportedException($"Unable to transpile from {sourceLanguage} to {targetLanguage}."); } mpqArchiveBuilder.RemoveFile("war3map.j"); mpqArchiveBuilder.RemoveFile(@"Scripts\war3map.j"); var jassHelperFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Warcraft III", "JassHelper"); if (string.IsNullOrEmpty(commonJPath)) { if (Directory.Exists(jassHelperFolder)) { commonJPath = Path.Combine(jassHelperFolder, "common.j"); if (string.IsNullOrEmpty(blizzardJPath)) { blizzardJPath = Path.Combine(jassHelperFolder, "Blizzard.j"); } } else { throw new DirectoryNotFoundException("Unable to automatically find common.j and Blizzard.j folder."); } } var mapHasCustomBlizzardJ = mapArchive.FileExists(@"Scripts\Blizzard.j"); if (string.IsNullOrEmpty(blizzardJPath) && !mapHasCustomBlizzardJ) { if (Directory.Exists(jassHelperFolder)) { blizzardJPath = Path.Combine(jassHelperFolder, "Blizzard.j"); } else { throw new DirectoryNotFoundException("Unable to automatically find common.j and Blizzard.j folder."); } } var estimatedWorkToTranspile = map.Script.Length + 700000; var estimatedWorkToRegisterCommonAndBlizzard = 35000000 / estimatedWorkToTranspile; if (estimatedWorkToRegisterCommonAndBlizzard == 0) { estimatedWorkToRegisterCommonAndBlizzard = 1; } var transpiler = new JassToLuaTranspiler(); transpiler.RegisterJassFile(JassSyntaxFactory.ParseCompilationUnit(File.ReadAllText(commonJPath))); worker?.ReportProgress(estimatedWorkToRegisterCommonAndBlizzard); if (mapHasCustomBlizzardJ) { throw new NotImplementedException("Custom Blizzard.j files are currently not supported."); } else { transpiler.RegisterJassFile(JassSyntaxFactory.ParseCompilationUnit(File.ReadAllText(blizzardJPath))); worker?.ReportProgress(estimatedWorkToRegisterCommonAndBlizzard * 2); } var luaCompilationUnit = transpiler.Transpile(JassSyntaxFactory.ParseCompilationUnit(map.Script)); using var stream = new MemoryStream(); using (var writer = new StreamWriter(stream, leaveOpen: true)) { var luaRenderOptions = new LuaSyntaxGenerator.SettingInfo { // Indent = 4, // IsCommentsDisabled = true, }; var luaRenderer = new LuaRenderer(luaRenderOptions, writer); luaRenderer.RenderCompilationUnit(luaCompilationUnit); writer.Flush(); } stream.Position = 0; mpqArchiveBuilder.AddFile(MpqFile.New(stream, targetFileName)); worker?.ReportProgress(100); var mpqArchiveCreateOptions = new MpqArchiveCreateOptions { }; mpqArchiveBuilder.SaveTo(outputFile, mpqArchiveCreateOptions); } else if (sourceLanguage == ScriptLanguage.Lua) { mpqArchiveBuilder.RemoveFile("war3map.lua"); mpqArchiveBuilder.RemoveFile(@"Scripts\war3map.lua"); throw new NotSupportedException($"Unable to transpile from {sourceLanguage} to {targetLanguage}."); } else { throw new NotSupportedException($"Unable to transpile from {sourceLanguage} to {targetLanguage}."); } }
private static void SaveArchiveBackgroundWork(object?sender, DoWorkEventArgs e) { var archiveBuilder = new MpqArchiveBuilder(_archive); var progress = new SaveArchiveProgress(); progress.Saving = false; for (var i = 0; i < _fileList.Items.Count; i++) { var tag = _fileList.Items[i].GetTag(); if (tag.Parent is not null) { continue; } if (tag.Status == MapFileStatus.Removed) { if (tag.TryGetHashedFileName(out var hashedFileName)) { archiveBuilder.RemoveFile(hashedFileName); } else { archiveBuilder.RemoveFile(_archive, tag.MpqEntry); } } else if (tag.Children is not null) { if (tag.Children.All(child => child.Status == MapFileStatus.Removed)) { throw new InvalidOperationException("Parent tag should have been removed since all child tags are removed, but was " + tag.Status); } else if (tag.Children.Any(child => child.IsModified || child.Status == MapFileStatus.Removed)) { // Assume at most one nested archive (for campaign archives), so no recursion. using var subArchive = MpqArchive.Open(_archive.OpenFile(tag.FileName)); foreach (var child in tag.Children) { if (child.FileName != null) { subArchive.AddFileName(child.FileName); } } var subArchiveBuilder = new MpqArchiveBuilder(subArchive); foreach (var child in tag.Children) { if (child.Status == MapFileStatus.Removed) { if (child.TryGetHashedFileName(out var hashedFileName)) { subArchiveBuilder.RemoveFile(hashedFileName); } else { subArchiveBuilder.RemoveFile(subArchive, child.MpqEntry); } } else if (child.TryGetModifiedMpqFile(out var subArchiveAdaptedFile)) { subArchiveBuilder.AddFile(subArchiveAdaptedFile); _saveArchiveWorker.ReportProgress(0, progress); } else { _saveArchiveWorker.ReportProgress(0, progress); } } var adaptedSubArchiveStream = new MemoryStream(); subArchiveBuilder.SaveWithPreArchiveData(adaptedSubArchiveStream, true); adaptedSubArchiveStream.Position = 0; var adaptedFile = MpqFile.New(adaptedSubArchiveStream, tag.FileName, false); adaptedFile.TargetFlags = tag.MpqEntry.Flags; archiveBuilder.AddFile(adaptedFile); _saveArchiveWorker.ReportProgress(0, progress); } else { _saveArchiveWorker.ReportProgress(tag.Children.Length, progress); } } else if (tag.TryGetModifiedMpqFile(out var adaptedFile)) { archiveBuilder.AddFile(adaptedFile); _saveArchiveWorker.ReportProgress(0, progress); } else { _saveArchiveWorker.ReportProgress(0, progress); } } progress.Saving = true; _saveArchiveWorker.ReportProgress(0, progress); using (var fileStream = File.Create((string)e.Argument)) { archiveBuilder.SaveWithPreArchiveData(fileStream); } }
public void Add(string inputFile, string fileName) { mpqArchiveBuilder?.RemoveFile(fileName); mpqArchiveBuilder?.AddFile(MpqFile.New(File.OpenRead(inputFile), fileName)); }
public void TranspileAndSaveTest(string inputFile, string outputFile, ScriptLanguage targetLanguage) { var targetFileName = targetLanguage switch { ScriptLanguage.Jass => "war3map.j", ScriptLanguage.Lua => "war3map.lua", _ => throw new InvalidEnumArgumentException(nameof(targetLanguage), (int)targetLanguage, typeof(ScriptLanguage)), }; using var mapArchive = MpqArchive.Open(inputFile, true); var map = Map.Open(mapArchive); var sourceLanguage = map.Info.ScriptLanguage; var mpqArchiveBuilder = new MpqArchiveBuilder(mapArchive); using var mapInfoStream = new MemoryStream(); using var mapInfoWriter = new BinaryWriter(mapInfoStream); var mapInfo = map.Info; mapInfo.ScriptLanguage = targetLanguage; if (mapInfo.FormatVersion < MapInfoFormatVersion.Lua) { mapInfo.FormatVersion = MapInfoFormatVersion.Lua; if (mapInfo.GameVersion is null) { mapInfo.GameVersion = GamePatchVersionProvider.GetGameVersion(War3Net.Build.Common.GamePatch.v1_31_1); } } mapInfoWriter.Write(mapInfo); mapInfoStream.Position = 0; mpqArchiveBuilder.AddFile(MpqFile.New(mapInfoStream, MapInfo.FileName)); if (sourceLanguage == ScriptLanguage.Jass) { if (targetLanguage != ScriptLanguage.Lua) { throw new NotSupportedException($"Unable to transpile from {sourceLanguage} to {targetLanguage}."); } mpqArchiveBuilder.RemoveFile("war3map.j"); mpqArchiveBuilder.RemoveFile(@"Scripts\war3map.j"); using var reader = new StreamReader(@"C:\Users\Stan\Google Drive\PHP Projects\Files\common.j"); var commonJ = JassSyntaxFactory.ParseCompilationUnit(reader.ReadToEnd()); using var reader2 = new StreamReader(@"C:\Users\Stan\Google Drive\PHP Projects\Files\blizzard.j"); var blizzardJ = JassSyntaxFactory.ParseCompilationUnit(reader2.ReadToEnd()); var transpiler = new JassToLuaTranspiler(); transpiler.RegisterJassFile(commonJ); transpiler.RegisterJassFile(blizzardJ); var script = mapArchive.OpenFile("war3map.j"); using var reader3 = new StreamReader(script); var luaCompilationUnit = transpiler.Transpile(JassSyntaxFactory.ParseCompilationUnit(reader3.ReadToEnd())); script.Close(); var tempFileName = Path.GetTempFileName(); try { using (var writer = new StreamWriter(tempFileName)) { var luaRenderOptions = new LuaSyntaxGenerator.SettingInfo { // Indent = 4, // IsCommentsDisabled = true, }; var luaRenderer = new LuaRenderer(luaRenderOptions, writer); luaRenderer.RenderCompilationUnit(luaCompilationUnit); } using var fileStream = File.OpenRead(tempFileName); mpqArchiveBuilder.AddFile(MpqFile.New(fileStream, targetFileName)); var mpqArchiveCreateOptions = new MpqArchiveCreateOptions { AttributesCreateMode = MpqFileCreateMode.Prune, }; mpqArchiveBuilder.SaveTo(outputFile, mpqArchiveCreateOptions); } finally { File.Delete(tempFileName); } } else if (sourceLanguage == ScriptLanguage.Lua) { throw new NotSupportedException($"Unable to transpile from {sourceLanguage} to {targetLanguage}."); } else { throw new NotSupportedException($"Unable to transpile from {sourceLanguage} to {targetLanguage}."); } }