//@todo move this public static List<DeploymentContext> CreateDeploymentContext(ProjectParams Params, bool InDedicatedServer, bool DoCleanStage = false) { ParamList<string> ListToProcess = InDedicatedServer && (Params.Cook || Params.CookOnTheFly) ? Params.ServerCookedTargets : Params.ClientCookedTargets; var ConfigsToProcess = InDedicatedServer && (Params.Cook || Params.CookOnTheFly) ? Params.ServerConfigsToBuild : Params.ClientConfigsToBuild; var CreateWebSocketsServer = Params.ServerTargetPlatforms.Count() > 0 && Params.ClientTargetPlatforms.Contains(UnrealTargetPlatform.HTML5); List<UnrealTargetPlatform> PlatformsToStage = Params.ClientTargetPlatforms; if (InDedicatedServer && (Params.Cook || Params.CookOnTheFly)) { PlatformsToStage = Params.ServerTargetPlatforms; } bool prefixArchiveDir = false; if (PlatformsToStage.Contains(UnrealTargetPlatform.Win32) && PlatformsToStage.Contains(UnrealTargetPlatform.Win64)) { prefixArchiveDir = true; } List<DeploymentContext> DeploymentContexts = new List<DeploymentContext>(); foreach (var StagePlatform in PlatformsToStage) { // Get the platform to get cooked data from, may differ from the stage platform UnrealTargetPlatform CookedDataPlatform = Params.GetCookedDataPlatformForClientTarget(StagePlatform); if (InDedicatedServer && (Params.Cook || Params.CookOnTheFly)) { CookedDataPlatform = Params.GetCookedDataPlatformForServerTarget(StagePlatform); } List<string> ExecutablesToStage = new List<string>(); string PlatformName = StagePlatform.ToString(); string StageArchitecture = !String.IsNullOrEmpty(Params.SpecifiedArchitecture) ? Params.SpecifiedArchitecture : ""; foreach (var Target in ListToProcess) { foreach (var Config in ConfigsToProcess) { string Exe = Target; if (Config != UnrealTargetConfiguration.Development) { Exe = Target + "-" + PlatformName + "-" + Config.ToString() + StageArchitecture; } ExecutablesToStage.Add(Exe); } } string StageDirectory = ((ShouldCreatePak(Params) || (Params.Stage)) || !String.IsNullOrEmpty(Params.StageDirectoryParam)) ? Params.BaseStageDirectory : ""; string ArchiveDirectory = (Params.Archive || !String.IsNullOrEmpty(Params.ArchiveDirectoryParam)) ? Params.BaseArchiveDirectory : ""; if (prefixArchiveDir && (StagePlatform == UnrealTargetPlatform.Win32 || StagePlatform == UnrealTargetPlatform.Win64)) { if (Params.Stage) { StageDirectory = CombinePaths(Params.BaseStageDirectory, StagePlatform.ToString()); } if (Params.Archive) { ArchiveDirectory = CombinePaths(Params.BaseArchiveDirectory, StagePlatform.ToString()); } } string EngineDir = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine"); List<TargetReceipt> TargetsToStage = new List<TargetReceipt>(); foreach(string Target in ListToProcess) { foreach(UnrealTargetConfiguration Config in ConfigsToProcess) { string ReceiptBaseDir = Params.IsCodeBasedProject? Path.GetDirectoryName(Params.RawProjectPath) : EngineDir; Platform PlatformInstance = Platform.Platforms[StagePlatform]; UnrealTargetPlatform[] SubPlatformsToStage = PlatformInstance.GetStagePlatforms(); // if we are attempting to gathering multiple platforms, the files aren't required bool bRequireStagedFilesToExist = SubPlatformsToStage.Length == 1 && PlatformsToStage.Count == 1; foreach (UnrealTargetPlatform ReceiptPlatform in SubPlatformsToStage) { string Architecture = Params.SpecifiedArchitecture; if (string.IsNullOrEmpty(Architecture)) { Architecture = ""; var BuildPlatform = UEBuildPlatform.GetBuildPlatform(ReceiptPlatform, true); if (BuildPlatform != null) { Architecture = BuildPlatform.GetActiveArchitecture(); } } string ReceiptFileName = TargetReceipt.GetDefaultPath(ReceiptBaseDir, Target, ReceiptPlatform, Config, Architecture); if(!File.Exists(ReceiptFileName)) { if (bRequireStagedFilesToExist) { // if we aren't collecting multiple platforms, then it is expected to exist throw new AutomationException(ErrorCodes.Error_MissingExecutable, "Stage Failed. Missing receipt '{0}'. Check that this target has been built.", Path.GetFileName(ReceiptFileName)); } else { // if it's multiple platforms, then allow missing receipts continue; } } // Read the receipt for this target TargetReceipt Receipt; if(!TargetReceipt.TryRead(ReceiptFileName, out Receipt)) { throw new AutomationException("Missing or invalid target receipt ({0})", ReceiptFileName); } // Convert the paths to absolute Receipt.ExpandPathVariables(EngineDir, Path.GetDirectoryName(Params.RawProjectPath)); Receipt.SetDependenciesToBeRequired(bRequireStagedFilesToExist); TargetsToStage.Add(Receipt); } } } //@todo should pull StageExecutables from somewhere else if not cooked var SC = new DeploymentContext(Params.RawProjectPath, CmdEnv.LocalRoot, StageDirectory, ArchiveDirectory, Params.CookFlavor, Params.GetTargetPlatformInstance(CookedDataPlatform), Params.GetTargetPlatformInstance(StagePlatform), ConfigsToProcess, TargetsToStage, ExecutablesToStage, InDedicatedServer, Params.Cook || Params.CookOnTheFly, Params.CrashReporter && !(StagePlatform == UnrealTargetPlatform.Linux && Params.Rocket), // can't include the crash reporter from binary Linux builds Params.Stage, Params.CookOnTheFly, Params.Archive, Params.IsProgramTarget, Params.HasDedicatedServerAndClient, bInUseWebsocketNetDriver: CreateWebSocketsServer ); LogDeploymentContext(SC); // If we're a derived platform make sure we're at the end, otherwise make sure we're at the front if (CookedDataPlatform != StagePlatform) { DeploymentContexts.Add(SC); } else { DeploymentContexts.Insert(0, SC); } } return DeploymentContexts; }
//@todo move this public static List<DeploymentContext> CreateDeploymentContext(ProjectParams Params, bool InDedicatedServer, bool DoCleanStage = false) { ParamList<string> ListToProcess = InDedicatedServer && (Params.Cook || Params.CookOnTheFly) ? Params.ServerCookedTargets : Params.ClientCookedTargets; var ConfigsToProcess = InDedicatedServer && (Params.Cook || Params.CookOnTheFly) ? Params.ServerConfigsToBuild : Params.ClientConfigsToBuild; List<UnrealTargetPlatform> PlatformsToStage = Params.ClientTargetPlatforms; if (InDedicatedServer && (Params.Cook || Params.CookOnTheFly)) { PlatformsToStage = Params.ServerTargetPlatforms; } bool prefixArchiveDir = false; if (PlatformsToStage.Contains(UnrealTargetPlatform.Win32) && PlatformsToStage.Contains(UnrealTargetPlatform.Win64)) { prefixArchiveDir = true; } List<DeploymentContext> DeploymentContexts = new List<DeploymentContext>(); foreach (var StagePlatform in PlatformsToStage) { // Get the platform to get cooked data from, may differ from the stage platform UnrealTargetPlatform CookedDataPlatform = Params.GetCookedDataPlatformForClientTarget(StagePlatform); if (InDedicatedServer && (Params.Cook || Params.CookOnTheFly)) { CookedDataPlatform = Params.GetCookedDataPlatformForServerTarget(StagePlatform); } List<string> ExecutablesToStage = new List<string>(); string PlatformName = StagePlatform.ToString(); foreach (var Target in ListToProcess) { foreach (var Config in ConfigsToProcess) { string Exe = Target; if (Config != UnrealTargetConfiguration.Development) { Exe = Target + "-" + PlatformName + "-" + Config.ToString(); } ExecutablesToStage.Add(Exe); } } string StageDirectory = (Params.Stage || !String.IsNullOrEmpty(Params.StageDirectoryParam)) ? Params.BaseStageDirectory : ""; string ArchiveDirectory = (Params.Archive || !String.IsNullOrEmpty(Params.ArchiveDirectoryParam)) ? Params.BaseArchiveDirectory : ""; if (prefixArchiveDir && (StagePlatform == UnrealTargetPlatform.Win32 || StagePlatform == UnrealTargetPlatform.Win64)) { if (Params.Stage) { StageDirectory = CombinePaths(Params.BaseStageDirectory, StagePlatform.ToString()); } if (Params.Archive) { ArchiveDirectory = CombinePaths(Params.BaseArchiveDirectory, StagePlatform.ToString()); } } //@todo should pull StageExecutables from somewhere else if not cooked var SC = new DeploymentContext(Params.RawProjectPath, CmdEnv.LocalRoot, StageDirectory, ArchiveDirectory, Params.CookFlavor, Params.GetTargetPlatformInstance(CookedDataPlatform), Params.GetTargetPlatformInstance(StagePlatform), ConfigsToProcess, ExecutablesToStage, InDedicatedServer, Params.Cook || Params.CookOnTheFly, Params.CrashReporter && (StagePlatform != UnrealTargetPlatform.Linux || !Params.Rocket), Params.Stage, Params.CookOnTheFly, Params.Archive, Params.IsProgramTarget, Params.HasDedicatedServerAndClient ); LogDeploymentContext(SC); // If we're a derived platform make sure we're at the end, otherwise make sure we're at the front if (CookedDataPlatform != StagePlatform) { DeploymentContexts.Add(SC); } else { DeploymentContexts.Insert(0, SC); } } return DeploymentContexts; }
//@todo move this public static List<DeploymentContext> CreateDeploymentContext(ProjectParams Params, bool InDedicatedServer, bool DoCleanStage = false) { ParamList<string> ListToProcess = InDedicatedServer && (Params.Cook || Params.CookOnTheFly) ? Params.ServerCookedTargets : Params.ClientCookedTargets; var ConfigsToProcess = InDedicatedServer && (Params.Cook || Params.CookOnTheFly) ? Params.ServerConfigsToBuild : Params.ClientConfigsToBuild; List<UnrealTargetPlatform> PlatformsToStage = Params.ClientTargetPlatforms; if ( InDedicatedServer && (Params.Cook || Params.CookOnTheFly) ) { PlatformsToStage = Params.ServerTargetPlatforms; } List<DeploymentContext> DeploymentContexts = new List<DeploymentContext>(); foreach ( var StagePlatform in PlatformsToStage ) { List<string> ExecutablesToStage = new List<string>(); string PlatformName = StagePlatform.ToString(); foreach (var Target in ListToProcess) { foreach (var Config in ConfigsToProcess) { string Exe = Target; if (Config != UnrealTargetConfiguration.Development) { Exe = Target + "-" + PlatformName + "-" + Config.ToString(); } ExecutablesToStage.Add(Exe); } } //@todo should pull StageExecutables from somewhere else if not cooked var SC = new DeploymentContext(Params.RawProjectPath, CmdEnv.LocalRoot, (Params.Stage || !String.IsNullOrEmpty(Params.StageDirectoryParam)) ? Params.BaseStageDirectory : "", (Params.Archive || !String.IsNullOrEmpty(Params.ArchiveDirectoryParam)) ? Params.BaseArchiveDirectory : "", Params.CookFlavor, Params.GetTargetPlatformInstance(StagePlatform), ConfigsToProcess, ExecutablesToStage, InDedicatedServer, Params.Cook || Params.CookOnTheFly, Params.CrashReporter, Params.Stage, Params.CookOnTheFly, Params.Archive, Params.IsProgramTarget, Params.HasDedicatedServerAndClient ); LogDeploymentContext(SC); DeploymentContexts.Add(SC); } return DeploymentContexts; }
public static void Cook(ProjectParams Params) { if ((!Params.Cook && !(Params.CookOnTheFly && !Params.SkipServer)) || Params.SkipCook) { return; } Params.ValidateAndLog(); Log("********** COOK COMMAND STARTED **********"); string UE4EditorExe = HostPlatform.Current.GetUE4ExePath(Params.UE4Exe); if (!FileExists(UE4EditorExe)) { throw new AutomationException("Missing " + UE4EditorExe + " executable. Needs to be built first."); } if (Params.CookOnTheFly && !Params.SkipServer) { if (Params.ClientTargetPlatforms.Count > 0) { var LogFolderOutsideOfSandbox = GetLogFolderOutsideOfSandbox(); if (!GlobalCommandLine.Installed) { // In the installed runs, this is the same folder as CmdEnv.LogFolder so delete only in not-installed DeleteDirectory(LogFolderOutsideOfSandbox); CreateDirectory(LogFolderOutsideOfSandbox); } var ServerLogFile = CombinePaths(LogFolderOutsideOfSandbox, "Server.log"); Platform ClientPlatformInst = Params.ClientTargetPlatformInstances[0]; string TargetCook = ClientPlatformInst.GetCookPlatform(false, Params.HasDedicatedServerAndClient, Params.CookFlavor); ServerProcess = RunCookOnTheFlyServer(Params.RawProjectPath, Params.NoClient ? "" : ServerLogFile, TargetCook, Params.RunCommandline); if (ServerProcess != null) { Log("Waiting a few seconds for the server to start..."); Thread.Sleep(5000); } } else { throw new AutomationException("Failed to run, client target platform not specified"); } } else { var PlatformsToCook = new HashSet<string>(); if (!Params.NoClient) { foreach (var ClientPlatform in Params.ClientTargetPlatforms) { // Use the data platform, sometimes we will copy another platform's data var DataPlatform = Params.GetCookedDataPlatformForClientTarget(ClientPlatform); PlatformsToCook.Add(Params.GetTargetPlatformInstance(DataPlatform).GetCookPlatform(false, Params.HasDedicatedServerAndClient, Params.CookFlavor)); } } if (Params.DedicatedServer) { foreach (var ServerPlatform in Params.ServerTargetPlatforms) { // Use the data platform, sometimes we will copy another platform's data var DataPlatform = Params.GetCookedDataPlatformForServerTarget(ServerPlatform); PlatformsToCook.Add(Params.GetTargetPlatformInstance(DataPlatform).GetCookPlatform(true, false, Params.CookFlavor)); } } if (Params.Clean.HasValue && Params.Clean.Value && !Params.IterativeCooking) { Log("Cleaning cooked data."); CleanupCookedData(PlatformsToCook.ToList(), Params); } // cook the set of maps, or the run map, or nothing string[] Maps = null; if (Params.HasMapsToCook) { Maps = Params.MapsToCook.ToArray(); } string[] Dirs = null; if (Params.HasDirectoriesToCook) { Dirs = Params.DirectoriesToCook.ToArray(); } string[] Cultures = null; if (Params.HasCulturesToCook) { Cultures = Params.CulturesToCook.ToArray(); } try { var CommandletParams = "-buildmachine -Unversioned -fileopenlog"; if (Params.UseDebugParamForEditorExe) { CommandletParams += " -debug"; } if (Params.Manifests) { CommandletParams += " -manifests"; } if (Params.IterativeCooking) { CommandletParams += " -iterate"; } CookCommandlet(Params.RawProjectPath, Params.UE4Exe, Maps, Dirs, Cultures, CombineCommandletParams(PlatformsToCook.ToArray()), CommandletParams); } catch (Exception Ex) { // Delete cooked data (if any) as it may be incomplete / corrupted. Log("Cook failed. Deleting cooked data."); CleanupCookedData(PlatformsToCook.ToList(), Params); AutomationTool.ErrorReporter.Error("Cook failed.", (int)AutomationTool.ErrorCodes.Error_UnknownCookFailure); throw Ex; } } Log("********** COOK COMMAND COMPLETED **********"); }
private static void DiffCookedContent( ProjectParams Params) { List<UnrealTargetPlatform> PlatformsToCook = Params.ClientTargetPlatforms; string ProjectPath = Path.GetFullPath(Params.RawProjectPath); var CookedSandboxesPath = CombinePaths(GetDirectoryName(ProjectPath), "Saved", "Cooked"); for (int CookPlatformIndex = 0; CookPlatformIndex < PlatformsToCook.Count; ++CookPlatformIndex) { // temporary directory to save the pak file to (pak file is usually not local and on network drive) var TemporaryPakPath = CombinePaths(GetDirectoryName(ProjectPath), "Saved", "Temp", "LocalPKG"); // extracted files from pak file var TemporaryFilesPath = CombinePaths(GetDirectoryName(ProjectPath), "Saved", "Temp", "LocalFiles"); try { Directory.Delete(TemporaryPakPath, true); Directory.Delete(TemporaryFilesPath, true); } catch(Exception ) { LogConsole("Failed deleting temporary directories "+TemporaryPakPath+" "+TemporaryFilesPath+" continuing."); } Directory.CreateDirectory(TemporaryPakPath); Directory.CreateDirectory(TemporaryFilesPath); Platform CurrentPlatform = Params.GetTargetPlatformInstance(PlatformsToCook[CookPlatformIndex]); if (Params.DiffCookedContentPath.EndsWith(".pak")) { string TemporaryPakFilename = CombinePaths( TemporaryPakPath, Path.GetFileName(Params.DiffCookedContentPath) ); File.Copy(Params.DiffCookedContentPath, TemporaryPakFilename); } else { CurrentPlatform.ExtractPackage(Params, Params.DiffCookedContentPath, TemporaryPakPath); } string FullCookPath = CombinePaths(CookedSandboxesPath, PlatformsToCook[CookPlatformIndex].ToString()); var UnrealPakExe = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/Win64/UnrealPak.exe"); // find the pak file var PakFiles = Directory.EnumerateFiles(TemporaryPakPath, "*.pak"); foreach (var Name in PakFiles) { string UnrealPakParams = Name + " -Extract " + " " + TemporaryFilesPath; RunAndLog(CmdEnv, UnrealPakExe, UnrealPakParams, Options: ERunOptions.Default | ERunOptions.UTF8Output); } // diff the content List<string> AllFiles = Directory.EnumerateFiles(FullCookPath, "*.uasset", System.IO.SearchOption.AllDirectories).ToList(); AllFiles.AddRange(Directory.EnumerateFiles(FullCookPath, "*.map", System.IO.SearchOption.AllDirectories).ToList()); foreach (string SourceFilename in AllFiles) { // Filename.StartsWith( CookedSandboxesPath ); string RelativeFilename = SourceFilename.Remove(0, FullCookPath.Length); string DestFilename = TemporaryFilesPath + RelativeFilename; byte[] SourceFile = File.ReadAllBytes(SourceFilename); byte[] DestFile = File.ReadAllBytes(DestFilename); if ( SourceFile.LongLength == DestFile.LongLength ) { for ( long Index = 0; Index < SourceFile.LongLength; ++Index ) { if ( SourceFile[Index] != DestFile[Index] ) { LogConsole("Diff cooked content failed on file " +SourceFilename + " when comparing against "+DestFilename + " at offset " + Index.ToString() ); break; } } } else { LogConsole("Diff cooked content failed on file " +SourceFilename + " when comparing against "+DestFilename + " files are different sizes " + SourceFile.LongLength.ToString() + " " + DestFile.LongLength.ToString() ); } } } }
public static void Cook(ProjectParams Params) { if ((!Params.Cook && !(Params.CookOnTheFly && !Params.SkipServer)) || Params.SkipCook) { return; } Params.ValidateAndLog(); LogConsole("********** COOK COMMAND STARTED **********"); string UE4EditorExe = HostPlatform.Current.GetUE4ExePath(Params.UE4Exe); if (!FileExists(UE4EditorExe)) { throw new AutomationException("Missing " + UE4EditorExe + " executable. Needs to be built first."); } if (Params.CookOnTheFly && !Params.SkipServer) { if (Params.HasDLCName) { throw new AutomationException("Cook on the fly doesn't support cooking dlc"); } if (Params.ClientTargetPlatforms.Count > 0) { var LogFolderOutsideOfSandbox = GetLogFolderOutsideOfSandbox(); if (!GlobalCommandLine.Installed) { // In the installed runs, this is the same folder as CmdEnv.LogFolder so delete only in not-installed DeleteDirectory(LogFolderOutsideOfSandbox); CreateDirectory(LogFolderOutsideOfSandbox); } String COTFCommandLine = Params.RunCommandline; if (Params.IterativeCooking) { COTFCommandLine += " -iterate"; } var ServerLogFile = CombinePaths(LogFolderOutsideOfSandbox, "Server.log"); Platform ClientPlatformInst = Params.ClientTargetPlatformInstances[0]; string TargetCook = ClientPlatformInst.GetCookPlatform(false, Params.HasDedicatedServerAndClient, Params.CookFlavor); ServerProcess = RunCookOnTheFlyServer(Params.RawProjectPath, Params.NoClient ? "" : ServerLogFile, TargetCook, COTFCommandLine); if (ServerProcess != null) { LogConsole("Waiting a few seconds for the server to start..."); Thread.Sleep(5000); } } else { throw new AutomationException("Failed to run, client target platform not specified"); } } else { var PlatformsToCook = new HashSet<string>(); if (!Params.NoClient) { foreach (var ClientPlatform in Params.ClientTargetPlatforms) { // Use the data platform, sometimes we will copy another platform's data var DataPlatform = Params.GetCookedDataPlatformForClientTarget(ClientPlatform); PlatformsToCook.Add(Params.GetTargetPlatformInstance(DataPlatform).GetCookPlatform(false, Params.HasDedicatedServerAndClient, Params.CookFlavor)); } } if (Params.DedicatedServer) { foreach (var ServerPlatform in Params.ServerTargetPlatforms) { // Use the data platform, sometimes we will copy another platform's data var DataPlatform = Params.GetCookedDataPlatformForServerTarget(ServerPlatform); PlatformsToCook.Add(Params.GetTargetPlatformInstance(DataPlatform).GetCookPlatform(true, false, Params.CookFlavor)); } } if (Params.Clean.HasValue && Params.Clean.Value && !Params.IterativeCooking) { LogConsole("Cleaning cooked data."); CleanupCookedData(PlatformsToCook.ToList(), Params); } // cook the set of maps, or the run map, or nothing string[] Maps = null; if (Params.HasMapsToCook) { Maps = Params.MapsToCook.ToArray(); foreach (var M in Maps) { LogConsole("HasMapsToCook " + M.ToString()); } foreach (var M in Params.MapsToCook) { LogConsole("Params.HasMapsToCook " + M.ToString()); } } string[] Dirs = null; if (Params.HasDirectoriesToCook) { Dirs = Params.DirectoriesToCook.ToArray(); } string InternationalizationPreset = null; if (Params.HasInternationalizationPreset) { InternationalizationPreset = Params.InternationalizationPreset; } string[] Cultures = null; if (Params.HasCulturesToCook) { Cultures = Params.CulturesToCook.ToArray(); } try { var CommandletParams = IsBuildMachine ? "-buildmachine -fileopenlog" : "-fileopenlog"; if (Params.UnversionedCookedContent) { CommandletParams += " -unversioned"; } if (Params.FastCook) { CommandletParams += " -FastCook"; } if (Params.UseDebugParamForEditorExe) { CommandletParams += " -debug"; } if (Params.Manifests) { CommandletParams += " -manifests"; } if (Params.IterativeCooking) { CommandletParams += " -iterate"; } if (Params.CookMapsOnly) { CommandletParams += " -mapsonly"; } if (Params.NewCook) { CommandletParams += " -newcook"; } if (Params.OldCook) { CommandletParams += " -oldcook"; } if (Params.CookAll) { CommandletParams += " -cookall"; } if (Params.CookMapsOnly) { CommandletParams += " -mapsonly"; } if (Params.HasCreateReleaseVersion) { CommandletParams += " -createreleaseversion=" + Params.CreateReleaseVersion; } if ( Params.SkipCookingEditorContent) { CommandletParams += " -skipeditorcontent"; } if ( Params.NumCookersToSpawn != 0) { CommandletParams += " -numcookerstospawn=" + Params.NumCookersToSpawn; } if (Params.HasDLCName) { CommandletParams += " -dlcname=" + Params.DLCName; if ( !Params.DLCIncludeEngineContent ) { CommandletParams += " -errorOnEngineContentUse"; } } // don't include the based on release version unless we are cooking dlc or creating a new release version // in this case the based on release version is used in packaging if (Params.HasBasedOnReleaseVersion && (Params.HasDLCName || Params.HasCreateReleaseVersion)) { CommandletParams += " -basedonreleaseversion=" + Params.BasedOnReleaseVersion; } // if we are not going to pak but we specified compressed then compress in the cooker ;) // otherwise compress the pak files if (!Params.Pak && !Params.SkipPak && Params.Compressed) { CommandletParams += " -compressed"; } if (Params.HasAdditionalCookerOptions) { string FormatedAdditionalCookerParams = Params.AdditionalCookerOptions.TrimStart(new char[] { '\"', ' ' }).TrimEnd(new char[] { '\"', ' ' }); CommandletParams += " "; CommandletParams += FormatedAdditionalCookerParams; } if (!Params.NoClient) { var MapsList = Maps == null ? new List<string>() : Maps.ToList(); foreach (var ClientPlatform in Params.ClientTargetPlatforms) { var DataPlatform = Params.GetCookedDataPlatformForClientTarget(ClientPlatform); CommandletParams += (Params.GetTargetPlatformInstance(DataPlatform).GetCookExtraCommandLine(Params)); MapsList.AddRange((Params.GetTargetPlatformInstance(ClientPlatform).GetCookExtraMaps())); } Maps = MapsList.ToArray(); } CookCommandlet(Params.RawProjectPath, Params.UE4Exe, Maps, Dirs, InternationalizationPreset, Cultures, CombineCommandletParams(PlatformsToCook.ToArray()), CommandletParams); } catch (Exception Ex) { if (Params.IgnoreCookErrors) { LogWarning("Ignoring cook failure."); } else { // Delete cooked data (if any) as it may be incomplete / corrupted. LogConsole("Cook failed. Deleting cooked data."); CleanupCookedData(PlatformsToCook.ToList(), Params); throw new AutomationException(ErrorCodes.Error_UnknownCookFailure, Ex, "Cook failed."); } } if (Params.HasDiffCookedContentPath) { try { DiffCookedContent(Params); } catch ( Exception Ex ) { // Delete cooked data (if any) as it may be incomplete / corrupted. LogConsole("Cook failed. Deleting cooked data."); CleanupCookedData(PlatformsToCook.ToList(), Params); throw new AutomationException(ErrorCodes.Error_UnknownCookFailure, Ex, "Cook failed."); } } } LogConsole("********** COOK COMMAND COMPLETED **********"); }