public static void Build(bool launch) { // Ensure these folders exist Directory.CreateDirectory(ASSETS_FOLDER_PATH); Directory.CreateDirectory(OUTPUT_FOLDER_PATH); // Load existing map data var map = Map.Open(BASE_MAP_PATH); var builder = new MapBuilder(map); builder.AddFiles(BASE_MAP_PATH, "*", SearchOption.AllDirectories); builder.AddFiles(ASSETS_FOLDER_PATH, "*", SearchOption.AllDirectories); // Set debug options if necessary, configure compiler var csc = DEBUG ? "-debug -define:DEBUG" : null; var csproj = Directory.EnumerateFiles(SOURCE_CODE_PROJECT_FOLDER_PATH, "*.csproj", SearchOption.TopDirectoryOnly).Single(); var compiler = new Compiler(csproj, OUTPUT_FOLDER_PATH, string.Empty, null, "", "", csc, false, null, string.Empty) { IsExportMetadata = true, IsModule = false, IsInlineSimpleProperty = false, IsPreventDebugObject = true, IsCommentsDisabled = !DEBUG }; // Collect required paths and compile var coreSystemFiles = CSharpLua.CoreSystem.CoreSystemProvider.GetCoreSystemFiles(); var blizzardJ = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Warcraft III/JassHelper/Blizzard.j"); var commonJ = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Warcraft III/JassHelper/common.j"); var compileResult = map.CompileScript(compiler, coreSystemFiles, blizzardJ, commonJ); // If compilation failed, output an error if (!compileResult.Success) { throw new Exception(compileResult.Diagnostics.First(x => x.Severity == DiagnosticSeverity.Error).GetMessage()); } // Update war3map.lua so you can inspect the generated Lua code easily File.WriteAllText(Path.Combine(OUTPUT_FOLDER_PATH, OUTPUT_SCRIPT_NAME), map.Script); // Build w3x file var archiveCreateOptions = new MpqArchiveCreateOptions { ListFileCreateMode = MpqFileCreateMode.Overwrite, AttributesCreateMode = MpqFileCreateMode.Prune, BlockSize = 3, }; builder.Build(Path.Combine(OUTPUT_FOLDER_PATH, OUTPUT_MAP_NAME), archiveCreateOptions); // Launch if that option was selected if (launch) { var wc3exe = ConfigurationManager.AppSettings["wc3exe"]; if (File.Exists(wc3exe)) { var commandLineArgs = new StringBuilder(); var isReforged = Version.Parse(FileVersionInfo.GetVersionInfo(wc3exe).FileVersion) >= new Version(1, 32); if (isReforged) { commandLineArgs.Append(" -launch"); } else if (GRAPHICS_API != null) { commandLineArgs.Append($" -graphicsapi {GRAPHICS_API}"); } if (!PAUSE_GAME_ON_LOSE_FOCUS) { commandLineArgs.Append(" -nowfpause"); } var mapPath = Path.Combine(OUTPUT_FOLDER_PATH, OUTPUT_MAP_NAME); var absoluteMapPath = new FileInfo(mapPath).FullName; commandLineArgs.Append($" -loadfile \"{absoluteMapPath}\""); Process.Start(wc3exe, commandLineArgs.ToString()); } else { throw new Exception("Please set wc3exe in Launcher/app.config to the path of your Warcraft III executable."); } } }
public static void SaveWithPreArchiveData(this MpqArchiveBuilder mpqArchiveBuilder, Stream stream, MpqArchiveCreateOptions createOptions, MapInfo mapInfo, bool leaveOpen = false) { mapInfo.WriteArchiveHeaderToStream(stream); mpqArchiveBuilder.SaveTo(stream, createOptions, leaveOpen); }
public static void SaveWithPreArchiveData(this MpqArchiveBuilder mpqArchiveBuilder, string fileName, MpqArchiveCreateOptions createOptions) { var mpqFiles = mpqArchiveBuilder.ToArray(); var campaignInfoFile = mpqFiles.SingleOrDefault(file => file.Name == CampaignInfoHashedFileName); if (campaignInfoFile is not null) { using var reader = new BinaryReader(campaignInfoFile.MpqStream, new UTF8Encoding(false, true), true); var campaignInfo = reader.ReadCampaignInfo(); campaignInfoFile.MpqStream.Position = 0; mpqArchiveBuilder.SaveWithPreArchiveData(fileName, createOptions, campaignInfo); } else { var mapInfoFile = mpqFiles.SingleOrDefault(file => file.Name == MapInfoHashedFileName); if (mapInfoFile is not null) { using var reader = new BinaryReader(mapInfoFile.MpqStream, new UTF8Encoding(false, true), true); var mapInfo = reader.ReadMapInfo(); mapInfoFile.MpqStream.Position = 0; mpqArchiveBuilder.SaveWithPreArchiveData(fileName, createOptions, mapInfo); } else { throw new FileNotFoundException($"Unable to find {CampaignInfo.FileName} or {MapInfo.FileName} file to use as source for pre-archive data."); } } }
public void Build(Stream stream, MpqArchiveCreateOptions createOptions, bool leaveOpen = false) { CreateArchiveBuilder().SaveWithPreArchiveData(stream, createOptions, leaveOpen); }
public static void SaveWithPreArchiveData(this MpqArchiveBuilder mpqArchiveBuilder, string fileName, MpqArchiveCreateOptions createOptions, MapInfo mapInfo) { using (var stream = FileProvider.CreateFileAndFolder(fileName)) { mapInfo.WriteArchiveHeaderToStream(stream); mpqArchiveBuilder.SaveTo(stream, createOptions); } }
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}."); } }
public void Build(string path, MpqArchiveCreateOptions createOptions) { CreateArchiveBuilder().SaveWithPreArchiveData(path, createOptions); }
public static void SaveMapWithPreArchiveData(this MpqArchiveBuilder mpqArchiveBuilder, Stream stream, MpqArchiveCreateOptions createOptions, MapInfo mapInfo, MapTriggerStrings?mapTriggerStrings, Encoding encoding, bool leaveOpen = false) { mapInfo.WriteArchiveHeaderToStream(stream, mapTriggerStrings, encoding); mpqArchiveBuilder.SaveTo(stream, createOptions, leaveOpen); }
public static void SaveCampaignWithPreArchiveData(this MpqArchiveBuilder mpqArchiveBuilder, Stream stream, MpqArchiveCreateOptions createOptions, CampaignInfo campaignInfo, CampaignTriggerStrings?campaignTriggerStrings, Encoding encoding, bool leaveOpen = false) { campaignInfo.WriteArchiveHeaderToStream(stream, campaignTriggerStrings, encoding); mpqArchiveBuilder.SaveTo(stream, createOptions, leaveOpen); }
public static void SaveCampaignWithPreArchiveData(this MpqArchiveBuilder mpqArchiveBuilder, string fileName, MpqArchiveCreateOptions createOptions, CampaignInfo campaignInfo, CampaignTriggerStrings?campaignTriggerStrings, Encoding encoding) { using (var stream = FileProvider.CreateFileAndFolder(fileName)) { campaignInfo.WriteArchiveHeaderToStream(stream, campaignTriggerStrings, encoding); mpqArchiveBuilder.SaveTo(stream, createOptions); } }
public static void SaveWithPreArchiveData(this MpqArchiveBuilder mpqArchiveBuilder, Stream stream, MpqArchiveCreateOptions createOptions, Encoding encoding, bool leaveOpen = false) { var mpqFiles = mpqArchiveBuilder.ToArray(); var campaignInfoFile = mpqFiles.SingleOrDefault(file => file.Name == CampaignInfoHashedFileName); if (campaignInfoFile is not null) { using var reader = new BinaryReader(campaignInfoFile.MpqStream, encoding, true); var campaignInfo = reader.ReadCampaignInfo(); campaignInfoFile.MpqStream.Position = 0; var campaignTriggerStringsFile = mpqFiles.SingleOrDefault(file => file.Name == CampaignTriggerStringsHashedFileName); if (campaignTriggerStringsFile is not null) { using var triggerStringsReader = new StreamReader(campaignTriggerStringsFile.MpqStream, encoding, leaveOpen: true); var campaignTriggerStrings = triggerStringsReader.ReadCampaignTriggerStrings(); campaignTriggerStringsFile.MpqStream.Position = 0; mpqArchiveBuilder.SaveCampaignWithPreArchiveData(stream, createOptions, campaignInfo, campaignTriggerStrings, encoding, leaveOpen); } else { mpqArchiveBuilder.SaveCampaignWithPreArchiveData(stream, createOptions, campaignInfo, encoding, leaveOpen); } } else { var mapInfoFile = mpqFiles.SingleOrDefault(file => file.Name == MapInfoHashedFileName); if (mapInfoFile is not null) { using var reader = new BinaryReader(mapInfoFile.MpqStream, encoding, true); var mapInfo = reader.ReadMapInfo(); mapInfoFile.MpqStream.Position = 0; var mapTriggerStringsFile = mpqFiles.SingleOrDefault(file => file.Name == MapTriggerStringsHashedFileName); if (mapTriggerStringsFile is not null) { using var triggerStringsReader = new StreamReader(mapTriggerStringsFile.MpqStream, encoding, leaveOpen: true); var mapTriggerStrings = triggerStringsReader.ReadMapTriggerStrings(); mapTriggerStringsFile.MpqStream.Position = 0; mpqArchiveBuilder.SaveMapWithPreArchiveData(stream, createOptions, mapInfo, mapTriggerStrings, encoding, leaveOpen); } else { mpqArchiveBuilder.SaveMapWithPreArchiveData(stream, createOptions, mapInfo, encoding, leaveOpen); } } else { throw new FileNotFoundException($"Unable to find {CampaignInfo.FileName} or {MapInfo.FileName} file to use as source for pre-archive data."); } } }
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}."); } }