public static int Build(Project project, bool forceBuild) { while (true) { // Reset counts (in case of a rebuild) SourceCodeDirectoryCount = 0; LaunchedAddonBuilders = 0; ExitedAddonBuilders = 0; NotBuiltDirectories = 0; if (forceBuild) { Console.WriteLine("Rebuilding..."); } if (project.ShutdownGameBeforeBuilding) { Game.Shutdown(new List <string> { "arma3", "arma3_x64" }); } string[] sourceCodeDirectories = GetSourceCodeDirectories(project.SourceDirectory); SourceCodeDirectoryCount = sourceCodeDirectories.Length; Console.WriteLine($"info: Found {SourceCodeDirectoryCount} source code directories"); if (project.Hashes == null) { project.Hashes = new Dictionary <string, Hash>(); } foreach (string sourceCodeDirectory in sourceCodeDirectories) { Hash hash = new Hash(sourceCodeDirectory); if (forceBuild) { BuildDirectory(sourceCodeDirectory, project); } else { if (project.Hashes.ContainsKey(sourceCodeDirectory)) { Hash selectedHash = project.Hashes[sourceCodeDirectory]; if (selectedHash.Sha1 == hash.Sha1) { NotBuiltDirectories++; Console.WriteLine($"info: Not building {Path.GetFileName(sourceCodeDirectory)} because it hasn't changed"); } else { BuildDirectory(sourceCodeDirectory, project); } } else { project.Hashes.Add(sourceCodeDirectory, new Hash()); BuildDirectory(sourceCodeDirectory, project); } } } // Wait until all builds are complete while (LaunchedAddonBuilders + NotBuiltDirectories != SourceCodeDirectoryCount || ExitedAddonBuilders + NotBuiltDirectories != SourceCodeDirectoryCount) { Thread.Sleep(100); } if (project.StartGameAfterBuilding) { Game.Launch(project.Game.GameExecutable, project.Game.GameExecutableArguments); } // If doesn't only have successful exit codes lock (OnBuilderExitLock) { // Check if any non-zero exit codes were present int exitCode = ExitCodes.All(v => v == 0) ? 0 : 1; if (NotBuiltDirectories == SourceCodeDirectoryCount) { if (!ConsoleUtility.AskYesNoQuestion("Rebuild?")) { return(exitCode); } continue; } project.Save(); return(exitCode); } } }