public static void MaybeConvertToLowerCase(ProjectParams Params, DeploymentContext SC)
    {
        var BuildPlatform = SC.StageTargetPlatform;

        if (BuildPlatform.DeployLowerCaseFilenames(false))
        {
            SC.NonUFSStagingFiles      = ConvertToLower(SC.NonUFSStagingFiles);
            SC.NonUFSStagingFilesDebug = ConvertToLower(SC.NonUFSStagingFilesDebug);
        }
        if (Params.UsePak(SC.StageTargetPlatform) && BuildPlatform.DeployPakInternalLowerCaseFilenames())
        {
            SC.UFSStagingFiles = ConvertToLower(SC.UFSStagingFiles);
        }
        else if (!Params.UsePak(SC.StageTargetPlatform) && BuildPlatform.DeployLowerCaseFilenames(true))
        {
            SC.UFSStagingFiles = ConvertToLower(SC.UFSStagingFiles);
        }
    }
예제 #2
0
    private static IProcessResult RunDedicatedServer(ProjectParams Params, string ServerLogFile, string AdditionalCommandLine)
    {
        ProjectParams ServerParams = new ProjectParams(Params);

        ServerParams.Devices = new ParamList <string>(Params.ServerDevice);

        if (ServerParams.ServerTargetPlatforms.Count == 0)
        {
            throw new AutomationException("No ServerTargetPlatform set for RunDedicatedServer.");
        }

        var DeployContextList = CreateDeploymentContext(ServerParams, true);

        if (DeployContextList.Count == 0)
        {
            throw new AutomationException("No DeployContextList for RunDedicatedServer.");
        }

        var SC = DeployContextList[0];

        var ServerApp = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/Win64/UE4Editor.exe");

        if (ServerParams.Cook)
        {
            List <string> Exes = SC.StageTargetPlatform.GetExecutableNames(SC);
            ServerApp = Exes[0];
        }
        var Args = ServerParams.Cook ? "" : (SC.ProjectArgForCommandLines + " ");

        Console.WriteLine(Params.ServerDeviceAddress);
        TargetPlatformDescriptor ServerPlatformDesc = ServerParams.ServerTargetPlatforms[0];

        if (ServerParams.Cook && ServerPlatformDesc.Type == UnrealTargetPlatform.Linux && !String.IsNullOrEmpty(ServerParams.ServerDeviceAddress))
        {
            ServerApp = @"C:\Windows\system32\cmd.exe";

            string plinkPath = CombinePaths(Environment.GetEnvironmentVariable("LINUX_ROOT"), "bin/PLINK.exe ");
            string exePath   = CombinePaths(SC.ShortProjectName, "Binaries", ServerPlatformDesc.Type.ToString(), SC.ShortProjectName + "Server");
            if (ServerParams.ServerConfigsToBuild[0] != UnrealTargetConfiguration.Development)
            {
                exePath += "-" + ServerPlatformDesc.Type.ToString() + "-" + ServerParams.ServerConfigsToBuild[0].ToString();
            }
            exePath = CombinePaths("LinuxServer", exePath.ToLower()).Replace("\\", "/");
            Args    = String.Format("/k {0} -batch -ssh -t -i {1} {2}@{3} {4} {5} {6} -server -Messaging", plinkPath, ServerParams.DevicePassword, ServerParams.DeviceUsername, ServerParams.ServerDeviceAddress, exePath, Args, ServerParams.MapToRun);
        }
        else
        {
            var Map = ServerParams.MapToRun;
            if (!String.IsNullOrEmpty(ServerParams.AdditionalServerMapParams))
            {
                Map += ServerParams.AdditionalServerMapParams;
            }
            if (Params.FakeClient)
            {
                Map += "?fake";
            }

            Args += String.Format("{0} -server -abslog={1}  -unattended -log -Messaging", Map, CommandUtils.MakePathSafeToUseWithCommandLine(ServerLogFile));

            // Do not blindly add -nomcp, only do so if the client is using it
            if (Params.RunCommandline.Contains("-nomcp"))
            {
                Args += " -nomcp";
            }

            if (Params.ServerCommandline.Length > 0)
            {
                Args += " " + Params.ServerCommandline;
            }
        }

        if (ServerParams.UsePak(SC.StageTargetPlatform))
        {
            if (ServerParams.SignedPak)
            {
                Args += " -signedpak";
            }
            else
            {
                Args += " -pak";
            }
        }
        if (IsBuildMachine || Params.Unattended)
        {
            Args += " -buildmachine";
        }
        Args += " -CrashForUAT";
        Args += " " + AdditionalCommandLine;


        if (ServerParams.Cook && ServerPlatformDesc.Type == UnrealTargetPlatform.Linux && !String.IsNullOrEmpty(ServerParams.ServerDeviceAddress))
        {
            Args += String.Format(" 2>&1 > {0}", ServerLogFile);
        }

        PushDir(Path.GetDirectoryName(ServerApp));
        var Result = Run(ServerApp, Args, null, ERunOptions.AllowSpew | ERunOptions.NoWaitForExit | ERunOptions.AppMustExist | ERunOptions.NoStdOutRedirect);

        PopDir();

        return(Result);
    }
예제 #3
0
    private static void SetupClientParams(List <DeploymentContext> DeployContextList, ProjectParams Params, string ClientLogFile, out ERunOptions ClientRunFlags, out string ClientApp, out string ClientCmdLine)
    {
        if (Params.ClientTargetPlatforms.Count == 0)
        {
            throw new AutomationException("No ClientTargetPlatform set for SetupClientParams.");
        }

        //		var DeployContextList = CreateDeploymentContext(Params, false);

        if (DeployContextList.Count == 0)
        {
            throw new AutomationException("No DeployContextList for SetupClientParams.");
        }

        var SC = DeployContextList[0];

        // Get client app name and command line.
        ClientRunFlags = ERunOptions.AllowSpew | ERunOptions.AppMustExist;
        ClientApp      = "";
        ClientCmdLine  = "";
        string TempCmdLine  = "";
        var    PlatformName = Params.ClientTargetPlatforms[0].ToString();

        if (Params.Cook || Params.CookOnTheFly)
        {
            List <string> Exes = SC.StageTargetPlatform.GetExecutableNames(SC, true);
            ClientApp = Exes[0];
            if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS)
            {
                TempCmdLine += SC.ProjectArgForCommandLines + " ";
            }
            TempCmdLine += Params.MapToRun + " ";

            if (Params.CookOnTheFly || Params.FileServer)
            {
                TempCmdLine += "-filehostip=";
                bool FirstParam = true;
                if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
                {
                    NetworkInterface[] Interfaces = NetworkInterface.GetAllNetworkInterfaces();
                    foreach (NetworkInterface adapter in Interfaces)
                    {
                        if (adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback)
                        {
                            IPInterfaceProperties IP = adapter.GetIPProperties();
                            for (int Index = 0; Index < IP.UnicastAddresses.Count; ++Index)
                            {
                                if (IP.UnicastAddresses[Index].IsDnsEligible && IP.UnicastAddresses[Index].Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                {
                                    if (!IsNullOrEmpty(Params.Port))
                                    {
                                        foreach (var Port in Params.Port)
                                        {
                                            if (!FirstParam)
                                            {
                                                TempCmdLine += "+";
                                            }
                                            FirstParam = false;
                                            string[] PortProtocol = Port.Split(new char[] { ':' });
                                            if (PortProtocol.Length > 1)
                                            {
                                                TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], IP.UnicastAddresses[Index].Address.ToString(), PortProtocol[1]);
                                            }
                                            else
                                            {
                                                TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                                TempCmdLine += ":";
                                                TempCmdLine += Params.Port;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (!FirstParam)
                                        {
                                            TempCmdLine += "+";
                                        }
                                        FirstParam = false;

                                        // use default port
                                        TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    NetworkInterface[] Interfaces = NetworkInterface.GetAllNetworkInterfaces();
                    foreach (NetworkInterface adapter in Interfaces)
                    {
                        if (adapter.OperationalStatus == OperationalStatus.Up)
                        {
                            IPInterfaceProperties IP = adapter.GetIPProperties();
                            for (int Index = 0; Index < IP.UnicastAddresses.Count; ++Index)
                            {
                                if (IP.UnicastAddresses[Index].IsDnsEligible)
                                {
                                    if (!IsNullOrEmpty(Params.Port))
                                    {
                                        foreach (var Port in Params.Port)
                                        {
                                            if (!FirstParam)
                                            {
                                                TempCmdLine += "+";
                                            }
                                            FirstParam = false;
                                            string[] PortProtocol = Port.Split(new char[] { ':' });
                                            if (PortProtocol.Length > 1)
                                            {
                                                TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], IP.UnicastAddresses[Index].Address.ToString(), PortProtocol[1]);
                                            }
                                            else
                                            {
                                                TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                                TempCmdLine += ":";
                                                TempCmdLine += Params.Port;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (!FirstParam)
                                        {
                                            TempCmdLine += "+";
                                        }
                                        FirstParam = false;

                                        // use default port
                                        TempCmdLine += IP.UnicastAddresses[Index].Address.ToString();
                                    }
                                }
                            }
                        }
                    }
                }

                const string LocalHost = "127.0.0.1";

                if (!IsNullOrEmpty(Params.Port))
                {
                    foreach (var Port in Params.Port)
                    {
                        if (!FirstParam)
                        {
                            TempCmdLine += "+";
                        }
                        FirstParam = false;
                        string[] PortProtocol = Port.Split(new char[] { ':' });
                        if (PortProtocol.Length > 1)
                        {
                            TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], LocalHost, PortProtocol[1]);
                        }
                        else
                        {
                            TempCmdLine += LocalHost;
                            TempCmdLine += ":";
                            TempCmdLine += Params.Port;
                        }
                    }
                }
                else
                {
                    if (!FirstParam)
                    {
                        TempCmdLine += "+";
                    }
                    FirstParam = false;

                    // use default port
                    TempCmdLine += LocalHost;
                }
                TempCmdLine += " ";

                if (Params.CookOnTheFlyStreaming)
                {
                    TempCmdLine += "-streaming ";
                }
                else if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS)
                {
                    // per josh, allowcaching is deprecated/doesn't make sense for iOS.
                    TempCmdLine += "-allowcaching ";
                }
            }
            else if (Params.UsePak(SC.StageTargetPlatform))
            {
                if (Params.SignedPak)
                {
                    TempCmdLine += "-signedpak ";
                }
                else
                {
                    TempCmdLine += "-pak ";
                }
            }
            else if (!Params.Stage)
            {
                var SandboxPath = CombinePaths(SC.RuntimeProjectRootDir, "Saved", "Cooked", SC.CookPlatform);
                if (!SC.StageTargetPlatform.LaunchViaUFE)
                {
                    TempCmdLine += "-sandbox=" + CommandUtils.MakePathSafeToUseWithCommandLine(SandboxPath) + " ";
                }
                else
                {
                    TempCmdLine += "-sandbox=\'" + SandboxPath + "\' ";
                }
            }
        }
        else
        {
            ClientApp    = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries", PlatformName, "UE4Editor.exe");
            TempCmdLine += SC.ProjectArgForCommandLines + " ";
            if (!Params.EditorTest)
            {
                TempCmdLine += "-game " + Params.MapToRun + " ";
            }
            else
            {
                TempCmdLine += Params.MapToRun + " ";
            }
        }
        if (Params.LogWindow)
        {
            // Without NoStdOutRedirect '-log' doesn't log anything to the window
            ClientRunFlags |= ERunOptions.NoStdOutRedirect;
            TempCmdLine    += "-log ";
        }
        else
        {
            TempCmdLine += "-stdout ";
        }
        if (Params.Unattended)
        {
            TempCmdLine += "-unattended ";
        }
        if (IsBuildMachine || Params.Unattended)
        {
            TempCmdLine += "-buildmachine ";
        }
        if (Params.CrashIndex > 0)
        {
            int RealIndex = Params.CrashIndex - 1;
            if (RealIndex < 0 || RealIndex >= CrashCommands.Count())
            {
                throw new AutomationException("CrashIndex {0} is out of range...max={1}", Params.CrashIndex, CrashCommands.Count());
            }
            TempCmdLine += String.Format("-execcmds=\"debug {0}\" ", CrashCommands[RealIndex]);
        }
        else if (Params.RunAutomationTest != "")
        {
            TempCmdLine += "-execcmds=\"automation list;runtests " + Params.RunAutomationTest + "\" ";
        }
        else if (Params.RunAutomationTests)
        {
            TempCmdLine += "-execcmds=\"automation list;runall\" ";
        }
        if (SC.StageTargetPlatform.UseAbsLog)
        {
            TempCmdLine += "-abslog=" + CommandUtils.MakePathSafeToUseWithCommandLine(ClientLogFile) + " ";
        }
        if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS && SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.Linux)
        {
            TempCmdLine += "-Messaging -nomcp -Windowed ";
        }
        else
        {
            // skip arguments which don't make sense for iOS
            TempCmdLine += "-Messaging -nomcp ";
        }
        if (Params.NullRHI && SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.Mac)         // all macs have GPUs, and currently the mac dies with nullrhi
        {
            TempCmdLine += "-nullrhi ";
        }
        if (Params.Deploy && !Params.CookOnTheFly && (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.PS4))
        {
            TempCmdLine += "-deployedbuild ";
        }

        TempCmdLine += "-CrashForUAT ";
        TempCmdLine += Params.RunCommandline;

        // todo: move this into the platform
        if (SC.StageTargetPlatform.LaunchViaUFE)
        {
            ClientCmdLine  = "-run=Launch ";
            ClientCmdLine += "-Device=" + Params.Devices[0];
            for (int DeviceIndex = 1; DeviceIndex < Params.Devices.Count; DeviceIndex++)
            {
                ClientCmdLine += "+" + Params.Devices[DeviceIndex];
            }
            ClientCmdLine += " ";
            ClientCmdLine += "-Exe=\"" + ClientApp + "\" ";
            ClientCmdLine += "-Targetplatform=" + Params.ClientTargetPlatforms[0].ToString() + " ";
            ClientCmdLine += "-Params=\"" + TempCmdLine + "\"";
            ClientApp      = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/Win64/UnrealFrontend.exe");

            Log("Launching via UFE:");
            Log("\tClientCmdLine: " + ClientCmdLine + "");
        }
        else
        {
            ClientCmdLine = TempCmdLine;
        }
    }
    /// <summary>
    /// Deploy the application on the current platform
    /// </summary>
    /// <param name="Params"></param>
    /// <param name="SC"></param>
    public override void Deploy(ProjectParams Params, DeploymentContext SC)
    {
        if (!String.IsNullOrEmpty(Params.ServerDeviceAddress))
        {
            string sourcePath = CombinePaths(Params.BaseStageDirectory, GetCookPlatform(Params.DedicatedServer, false, ""));
            string destPath   = Params.DeviceUsername + "@" + Params.ServerDeviceAddress + ":.";
            RunAndLog(CmdEnv, pscpPath, String.Format("-batch -i {0} -r {1} {2}", Params.DevicePassword, sourcePath, destPath));

            List <string> Exes = GetExecutableNames(SC);

            string binPath  = CombinePaths(GetCookPlatform(Params.DedicatedServer, false, ""), SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir, Path.GetFileName(Exes[0])).Replace("\\", "/");
            string iconPath = CombinePaths(GetCookPlatform(Params.DedicatedServer, false, ""), SC.RelativeProjectRootForStage, SC.ShortProjectName + ".png").Replace("\\", "/");

            string DesiredGLVersion = "4.3";

            // Begin Bash Shell Script
            string script = String.Format(@"#!/bin/bash
# Check for OpenGL4 support
glarg=''
if command -v glxinfo >/dev/null 2>&1 ; then
    export DISPLAY="":0""
    glversion=$(glxinfo | grep ""OpenGL version string:"" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')
    glmatch=$(echo -e ""$glversion\n{0}"" | sort -Vr | head -1)
    [[ ""$glmatch"" = ""$glversion"" ]] && glarg=' -opengl4'
fi

# Create .desktop file
cat > $HOME/Desktop/{1}.desktop << EOF
[Desktop Entry]
Type=Application
Name={2}
Comment=UE4 Game
Exec=$HOME/{3}{4}$glarg
Icon=$HOME/{5}
Terminal=false
Categories=Game;
EOF

# Set permissions
chmod 755 $HOME/{3}
chmod 700 $HOME/Desktop/{1}.desktop", DesiredGLVersion, SC.ShortProjectName, SC.ShortProjectName, binPath, (Params.UsePak(SC.StageTargetPlatform) ? " -pak" : ""), iconPath);
            // End Bash Shell Script

            string scriptFile = Path.GetTempFileName();
            File.WriteAllText(scriptFile, script);
            RunAndLog(CmdEnv, plinkPath, String.Format("-ssh -t -batch -l {0} -i {1} {2} -m {3}", Params.DeviceUsername, Params.DevicePassword, Params.ServerDeviceAddress, scriptFile));
            File.Delete(scriptFile);
        }
    }
    public static void ApplyStagingManifest(ProjectParams Params, DeploymentContext SC)
    {
        MaybeConvertToLowerCase(Params, SC);
        if (SC.Stage && !Params.NoCleanStage && !Params.SkipStage)
        {
            DeleteDirectory(SC.StageDirectory);
        }
        if (ShouldCreatePak(Params, SC))
        {
            if (Params.Manifests && DoesChunkPakManifestExist(Params, SC))
            {
                CreatePaksUsingChunkManifests(Params, SC);
            }
            else
            {
                CreatePakUsingStagingManifest(Params, SC);
            }
        }
        if (!SC.Stage || Params.SkipStage)
        {
            return;
        }
        DumpManifest(SC, CombinePaths(CmdEnv.LogFolder, "FinalCopy" + (SC.DedicatedServer ? "_Server" : "")), !Params.UsePak(SC.StageTargetPlatform));
        CopyUsingStagingManifest(Params, SC);

        var ThisPlatform = SC.StageTargetPlatform;

        ThisPlatform.PostStagingFileCopy(Params, SC);
    }
    public static void CreateStagingManifest(ProjectParams Params, DeploymentContext SC)
    {
        if (!Params.Stage)
        {
            return;
        }
        var ThisPlatform = SC.StageTargetPlatform;

        ThisPlatform.GetFilesToDeployOrStage(Params, SC);

        // Get the build.properties file
        // this file needs to be treated as a UFS file for casing, but NonUFS for being put into the .pak file
        // @todo: Maybe there should be a new category - UFSNotForPak
        string BuildPropertiesPath = CombinePaths(SC.LocalRoot, "Engine/Build");

        if (SC.StageTargetPlatform.DeployLowerCaseFilenames(true))
        {
            BuildPropertiesPath = BuildPropertiesPath.ToLower();
        }
        SC.StageFiles(StagedFileType.NonUFS, BuildPropertiesPath, "build.properties", false, null, null, true);

        // move the UE4Commandline.txt file to the root of the stage
        // this file needs to be treated as a UFS file for casing, but NonUFS for being put into the .pak file
        // @todo: Maybe there should be a new category - UFSNotForPak
        string CommandLineFile = "UE4CommandLine.txt";

        if (SC.StageTargetPlatform.DeployLowerCaseFilenames(true))
        {
            CommandLineFile = CommandLineFile.ToLower();
        }
        SC.StageFiles(StagedFileType.NonUFS, GetIntermediateCommandlineDir(SC), CommandLineFile, false, null, "", true, false);

        if (!Params.CookOnTheFly && !Params.SkipCookOnTheFly)         // only stage the UFS files if we are not using cook on the fly
        {
            ConfigCacheIni PlatformGameConfig = new ConfigCacheIni(SC.StageTargetPlatform.PlatformType, "Game", CommandUtils.GetDirectoryName(Params.RawProjectPath));

            // Initialize cultures to stage.
            List <string> CulturesToStage = null;

            // Use parameters if provided.
            if (Params.CulturesToCook != null && Params.CulturesToCook.Count > 0)
            {
                CulturesToStage = Params.CulturesToCook;
            }

            // Use configuration if otherwise lacking cultures to stage.
            if (CulturesToStage == null || CulturesToStage.Count == 0)
            {
                if (PlatformGameConfig != null)
                {
                    PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "CulturesToStage", out CulturesToStage);
                }
            }

            // Error if no cultures have been provided.
            if (CulturesToStage == null || CulturesToStage.Count == 0)
            {
                throw new AutomationException("No cultures were specified for cooking and packaging. This will lead to fatal errors when launching. Specify culture codes via commandline (-CookCultures=) or using project packaging settings (+CulturesToStage).");
            }

            // Engine ufs (content)
            SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Config"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform));             // TODO: Exclude localization data generation config files.

            if (Params.bUsesSlate)
            {
                if (Params.bUsesSlateEditorStyle)
                {
                    SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Editor/Slate"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform));
                }
                SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Slate"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform));
                SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Content/Slate"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Content/Slate"), true, !Params.UsePak(SC.StageTargetPlatform));
            }
            foreach (string Culture in CulturesToStage)
            {
                StageLocalizationDataForCulture(SC, Culture, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/Engine"), null, !Params.UsePak(SC.StageTargetPlatform));
            }
            SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Plugins"), "*.uplugin", true, null, null, true, !Params.UsePak(SC.StageTargetPlatform));

            // Game ufs (content)

            SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot), "*.uproject", false, null, CombinePaths(SC.RelativeProjectRootForStage), true, !Params.UsePak(SC.StageTargetPlatform));
            SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Config"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Config"), true, !Params.UsePak(SC.StageTargetPlatform));             // TODO: Exclude localization data generation config files.
            SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Plugins"), "*.uplugin", true, null, null, true, !Params.UsePak(SC.StageTargetPlatform));
            foreach (string Culture in CulturesToStage)
            {
                StageLocalizationDataForCulture(SC, Culture, CombinePaths(SC.ProjectRoot, "Content/Localization/Game"), CombinePaths(SC.RelativeProjectRootForStage, "Content/Localization/Game"), !Params.UsePak(SC.StageTargetPlatform));
            }

            // Stage any additional UFS and NonUFS paths specified in the project ini files; these dirs are relative to the game content directory
            if (PlatformGameConfig != null)
            {
                var           ProjectContentRoot = CombinePaths(SC.ProjectRoot, "Content");
                var           StageContentRoot   = CombinePaths(SC.RelativeProjectRootForStage, "Content");
                List <string> ExtraUFSDirs;
                if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsUFS", out ExtraUFSDirs))
                {
                    // Each string has the format '(Path="TheDirToStage")'
                    foreach (var PathStr in ExtraUFSDirs)
                    {
                        var PathParts = PathStr.Split('"');
                        if (PathParts.Length == 3)
                        {
                            var RelativePath = PathParts[1];
                            SC.StageFiles(StagedFileType.UFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, null, CombinePaths(StageContentRoot, RelativePath), true, !Params.UsePak(SC.StageTargetPlatform));
                        }
                    }
                }

                List <string> ExtraNonUFSDirs;
                if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsNonUFS", out ExtraNonUFSDirs))
                {
                    // Each string has the format '(Path="TheDirToStage")'
                    foreach (var PathStr in ExtraNonUFSDirs)
                    {
                        var PathParts = PathStr.Split('"');
                        if (PathParts.Length == 3)
                        {
                            var RelativePath = PathParts[1];
                            SC.StageFiles(StagedFileType.NonUFS, CombinePaths(ProjectContentRoot, RelativePath));
                        }
                    }
                }
            }

            StagedFileType StagedFileTypeForMovies = StagedFileType.NonUFS;
            if (Params.FileServer)
            {
                // UFS is required when using a file server
                StagedFileTypeForMovies = StagedFileType.UFS;
            }

            if (SC.StageTargetPlatform.StageMovies)
            {
                SC.StageFiles(StagedFileTypeForMovies, CombinePaths(SC.LocalRoot, "Engine/Content/Movies"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Engine/Content/Movies"), true, !Params.UsePak(SC.StageTargetPlatform));
                SC.StageFiles(StagedFileTypeForMovies, CombinePaths(SC.ProjectRoot, "Content/Movies"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Content/Movies"), true, !Params.UsePak(SC.StageTargetPlatform));
            }

            // eliminate the sand box
            SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Saved", "Cooked", SC.CookPlatform), "*", true, null, "", true, !Params.UsePak(SC.StageTargetPlatform));

            // CrashReportClient is a standalone slate app that does not look in the generated pak file, so it needs the Content/Slate and Shaders/StandaloneRenderer folders Non-UFS
            // @todo Make CrashReportClient more portable so we don't have to do this
            if (SC.bStageCrashReporter && UnrealBuildTool.UnrealBuildTool.PlatformSupportsCrashReporter(SC.StageTargetPlatform.PlatformType) && !SC.DedicatedServer)
            {
                //If the .dat file needs to be staged as NonUFS for non-Windows/Linux hosts we need to change the casing as we do with the build properties file above.
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Content/Slate"));
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Shaders/StandaloneRenderer"));

                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"));
                // Linux platform stages ICU in GetFilesToDeployOrStage(), accounting for the actual architecture
                if (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win64 ||
                    SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win32 ||
                    SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Mac)
                {
                    SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/ICU"));
                }

                // SSL libraries are only available for Win64 builds.
                // @see FPerforceSourceControlProvider::LoadSSLLibraries
                if (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win64)
                {
                    SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/OpenSSL"));
                }
            }
        }
    }
    public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC)
    {
        if (UnrealBuildTool.BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac)
        {
            // copy the icons/launch screens from the engine
            {
                string SourcePath = CombinePaths(SC.LocalRoot, "Engine", "Build", "IOS", "Resources", "Graphics");
                SC.StageFiles(StagedFileType.NonUFS, SourcePath, "*.png", false, null, "", true, false);
            }

            // copy any additional framework assets that will be needed at runtime
            {
                string SourcePath = CombinePaths((SC.IsCodeBasedProject ? SC.ProjectRoot : SC.LocalRoot + "\\Engine"), "Intermediate", "IOS", "FrameworkAssets");
                if (Directory.Exists(SourcePath))
                {
                    SC.StageFiles(StagedFileType.NonUFS, SourcePath, "*.*", true, null, "", true, false);
                }
            }

            // copy the icons/launch screens from the game (may stomp the engine copies)
            {
                string SourcePath = CombinePaths(SC.ProjectRoot, "Build", "IOS", "Resources", "Graphics");
                SC.StageFiles(StagedFileType.NonUFS, SourcePath, "*.png", false, null, "", true, false);
            }

            // copy the plist (only if code signing, as it's protected by the code sign blob in the executable and can't be modified independently)
            if (GetCodeSignDesirability(Params))
            {
                string SourcePListFile = CombinePaths(SC.LocalRoot, "Engine", "Build", "IOS", "UE4Game-Info.plist");
                if (File.Exists(SC.ProjectRoot + "/Build/IOS/Info.plist"))
                {
                    SourcePListFile = CombinePaths(SC.ProjectRoot, "Build", "IOS", "Info.plist");
                }
                else if (File.Exists(SC.ProjectRoot + "/Build/IOS/" + SC.ShortProjectName + "-Info.plist"))
                {
                    SourcePListFile = CombinePaths(SC.ProjectRoot, "Build", "IOS", SC.ShortProjectName + "-Info.plist");
                }
                else if (Directory.Exists(SC.ProjectRoot + "/Build/IOS"))
                {
                    // look for any plist file
                    string[] Plists = Directory.GetFiles(SC.ProjectRoot + "/Build/IOS", "*.plist");
                    if (Plists.Length > 0)
                    {
                        SourcePListFile = Plists[0];
                    }
                }

                //@TODO: This is writing to the engine directory!
                string SourcePath      = CombinePaths((SC.IsCodeBasedProject ? SC.ProjectRoot : SC.LocalRoot + "\\Engine"), "Intermediate", "IOS");
                string TargetPListFile = Path.Combine(SourcePath, (SC.IsCodeBasedProject ? SC.ShortProjectName : "UE4Game") + "-Info.plist");

                Dictionary <string, string> Replacements = new Dictionary <string, string>();
                Replacements.Add("${EXECUTABLE_NAME}", (SC.IsCodeBasedProject ? SC.ShortProjectName : "UE4Game"));
                Replacements.Add("${BUNDLE_IDENTIFIER}", SC.ShortProjectName.Replace("_", ""));
                CopyFileWithReplacements(SourcePListFile, TargetPListFile, Replacements);

                SC.StageFiles(StagedFileType.NonUFS, SourcePath, Path.GetFileName(TargetPListFile), false, null, "", false, false, "Info.plist");
            }
        }

        // copy the movies from the project
        {
            SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Build/IOS/Resources/Movies"), "*", false, null, "", true, false);
            SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Content/Movies"), "*", true, null, "", true, false);
        }

        // stage required icu files
        SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform));
    }
    public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC)
    {
        //      if (SC.StageExecutables.Count != 1 && Params.Package)
        //      {
        //          throw new AutomationException("Exactly one executable expected when staging Android. Had " + SC.StageExecutables.Count.ToString());
        //      }
        //
        //      // stage all built executables
        //      foreach (var Exe in SC.StageExecutables)
        //      {
        //          string ApkName = Exe + GetArchitecture(Params) + ".apk";
        //
        //          SC.StageFiles(StagedFileType.NonUFS, Params.ProjectBinariesFolder, ApkName);
        //      }

        if (!Params.CookOnTheFly && !Params.SkipCookOnTheFly)         // only stage the UFS files if we are not using cook on the fly
        {
            SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform));
        }
    }
    public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC)
    {
        if (SC.bStageCrashReporter)
        {
            SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "CrashReportClient", false);
        }

        {
            SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/ICU/icu4c-53_1/", SC.PlatformDir, "x86_64-unknown-linux-gnu"), Params.bDebugBuildsActuallyUseDebugCRT ? "*d.so*" : "*.so*", false, new[] { Params.bDebugBuildsActuallyUseDebugCRT ? "*.so*" : "*d.so*" }, CombinePaths("Engine/Binaries", SC.PlatformDir));
        }

        // assume that we always have to deploy Steam (FIXME: should be automatic)
        {
            string SteamVersion = "Steamv130";

            // Check if the Steam directory exists. We need it for Steam controller support, so we include it whenever we can.
            if (Directory.Exists(CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion)))
            {
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "libsteam_api.so", false, null, CombinePaths("Engine/Binaries", SC.PlatformDir));
            }

            SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Config"), "controller.vdf", false, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Saved/Config"));
            // copy optional perfcounters definition file
            SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Config"), "PerfCounters.json", false, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Saved/Config"), true);
        }

        // assume that we always have to deploy OpenAL (FIXME: should be automatic)
        {
            SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/OpenAL/", SC.PlatformDir), "libopenal.so.1", false, null, CombinePaths("Engine/Binaries", SC.PlatformDir));
        }

        SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Content/Splash"), "Splash.bmp", false, null, null, true);
        SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform));


        if (Params.StageNonMonolithic)
        {
            if (SC.DedicatedServer)
            {
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4Server");
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "libUE4Server-*.so");
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Plugins"), "libUE4Server-*.so", true, null, null, true);
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), "libUE4Server-*.so");
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins"), "libUE4Server-*.so", true, null, null, true);
            }
            else
            {
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4");
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "libUE4-*.so");
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Plugins"), "libUE4-*.so", true, null, null, true);
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), "libUE4-*.so");
                SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins"), "libUE4-*.so", true, null, null, true);
            }
        }
        else
        {
            List <string> Exes = GetExecutableNames(SC);

            foreach (var Exe in Exes)
            {
                if (Exe.StartsWith(CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir)))
                {
                    // remap the project root. For content-only projects, rename the executable to the project name.
                    if (!Params.IsCodeBasedProject && Exe == Exes[0])
                    {
                        SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(Exe), true, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir), false, true, SC.ShortProjectName);
                    }
                    else
                    {
                        SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(Exe), true, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir), false);
                    }
                }
                else if (Exe.StartsWith(CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir)))
                {
                    // Move the executable for content-only projects into the project directory, using the project name, so it can figure out the UProject to look for and is consistent with code projects.
                    if (!Params.IsCodeBasedProject && Exe == Exes[0])
                    {
                        SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(Exe), true, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir), false, true, SC.ShortProjectName);
                    }
                    else
                    {
                        SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(Exe), true, null, null, false);
                    }
                }
                else
                {
                    throw new AutomationException("Can't stage the exe {0} because it doesn't start with {1} or {2}", Exe, CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir), CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir));
                }
            }
        }
    }
예제 #10
0
    public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC)
    {
        List <string> Exes = GetExecutableNames(SC);

        foreach (var Exe in Exes)
        {
            if (Exe.StartsWith(CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir)))
            {
                StageAppBundle(SC, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app"), CombinePaths(SC.ShortProjectName, "Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app"));
            }
            else if (Exe.StartsWith(CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir)))
            {
                StageAppBundle(SC, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app"), CombinePaths("Engine/Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app"));
            }
        }

        // Copy the splash screen, Mac specific
        SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Content/Splash"), "Splash.bmp", false, null, null, true);

        SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform));
    }
    public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC)
    {
        // Engine non-ufs (binaries)

        if (SC.bStageCrashReporter)
        {
            StageExecutable("exe", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "CrashReportClient.");
        }

        //todo we need to support shipping and test executables
        //todo this should all be partially based on UBT manifests and not hard coded
        //monolithic assumption
        StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Ogg", SC.PlatformDir), "*.", true);
        StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Vorbis", SC.PlatformDir), "*.", true);
        string PhysXVer = "VS" + WindowsPlatform.GetVisualStudioCompilerVersionName();
        string ApexVer  = "VS" + WindowsPlatform.GetVisualStudioCompilerVersionName();
        string PhysXMaskForDebugConfiguration = Params.bDebugBuildsActuallyUseDebugCRT ? "*DEBUG*.*" : "*PROFILE*.*";

        if (SC.StageTargetConfigurations.Contains(UnrealTargetConfiguration.Debug) && !Params.Rocket)
        {
            StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/APEX-1.3", SC.PlatformDir, ApexVer), PhysXMaskForDebugConfiguration, true);
            StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/PhysX-3.3", SC.PlatformDir, PhysXVer), PhysXMaskForDebugConfiguration, true);
            StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/PhysX-3.3", SC.PlatformDir, PhysXVer), "nvToolsExt*.", true);
        }
        if (SC.StageTargetConfigurations.Any(x => x != UnrealTargetConfiguration.Debug) || Params.Rocket)
        {
            StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/APEX-1.3", SC.PlatformDir, ApexVer), "*.", true, new string[] { "*DEBUG*.*", "*CHECKED*.*" });
            StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/PhysX-3.3", SC.PlatformDir, PhysXVer), "*.", true, new string[] { "*DEBUG*.*", "*CHECKED*.*" });
        }

        if (Params.bUsesSteam)
        {
            string SteamVersion = "Steamv130";

            // Check that the TPS directory exists. We don't distribute binaries for Steam in Rocket.
            if (Directory.Exists(CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion)))
            {
                if (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win32)
                {
                    StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "steam_api.");
                    if (SC.DedicatedServer)
                    {
                        StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "steamclient.");
                        StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "tier0_s.");
                        StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "vstdlib_s.");
                    }
                }
                else
                {
                    StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "steam_api64.");
                    if (SC.DedicatedServer)
                    {
                        StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "steamclient64.");
                        StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "tier0_s64.");
                        StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "vstdlib_s64.");
                    }
                }
            }
        }

        // Copy the splash screen, windows specific
        SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Content/Splash"), "Splash.bmp", false, null, null, true);

        SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform));

        if (Params.StageNonMonolithic)
        {
            if (SC.DedicatedServer)
            {
                StageExecutable("exe", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4Server.");
                StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4Server-*.");
                StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Plugins"), "UE4Server-*.", true);
                StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), "UE4Server-*.");
                StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.ProjectRoot, "Plugins"), "UE4Server-*.", true);

                StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/ICU/icu4c-53_1", SC.PlatformDir, "VS2013"), "*.");
            }
            else
            {
                StageExecutable("exe", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4.");
                StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4-*.");
                StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Plugins"), "UE4-*.", true);
                StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), "UE4-*.");
                StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.ProjectRoot, "Plugins"), "UE4-*.", true);
            }
        }
        else
        {
            List <string> Exes = GetExecutableNames(SC);

            // the first exe is the "main" one, the rest are marked as debug files
            StagedFileType WorkingFileType = StagedFileType.NonUFS;

            foreach (var Exe in Exes)
            {
                if (Exe.StartsWith(CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir)))
                {
                    // remap the project root.
                    string SourceFile = CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir, Path.GetFileName(Exe));
                    StageExecutable("exe", SC, Path.GetDirectoryName(SourceFile), Path.GetFileNameWithoutExtension(SourceFile) + ".", true, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir), false, WorkingFileType);
                    if (Exe == Exes[0])
                    {
                        StageBootstrapExecutable(SC, SourceFile, CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir, Path.GetFileName(Exe)), "");
                    }
                }
                else if (Exe.StartsWith(CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir)))
                {
                    // keep it in the engine directory.
                    string SourceFile = CombinePaths(SC.LocalRoot, "Engine", "Binaries", SC.PlatformDir, Path.GetFileName(Exe));
                    StageExecutable("exe", SC, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(SourceFile) + ".", true, null, null, false, WorkingFileType);
                    if (Exe == Exes[0])
                    {
                        StageBootstrapExecutable(SC, SourceFile, CombinePaths("Engine", "Binaries", SC.PlatformDir, Path.GetFileName(Exe)), String.Format("..\\..\\..\\{0}\\{0}.uproject", SC.ShortProjectName));
                    }
                }
                else
                {
                    throw new AutomationException("Can't stage the exe {0} because it doesn't start with {1} or {2}", Exe, CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir), CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir));
                }
                // the first exe is the "main" one, the rest are marked as debug files
                WorkingFileType = StagedFileType.DebugNonUFS;
            }
        }
    }