public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); string DeviceSection; if ( Utils.IsRunningOnMono ) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } string browserPath; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); bool ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); if (!ok) throw new System.Exception ("Incorrect browser configuration in HTML5Engine.ini "); // open the webpage string directory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) +".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { var EmscriptenSettings = ReadEmscriptenSettings(); url = "http://127.0.0.1:8000/" + url; // this will be killed UBT instances dies. string input = String.Format(" -m SimpleHTTPServer 8000"); string PythonName = null; // Check the .emscripten file for a possible python path if (EmscriptenSettings.ContainsKey("PYTHON")) { PythonName = EmscriptenSettings["PYTHON"]; Log("Found python path {0} in emscripten file", PythonName); } // The AutoSDK defines this env var as part of its install. See setup.bat/unsetup.bat // If it's missing then just assume that python lives on the path if (PythonName == null && Environment.GetEnvironmentVariable("PYTHON") != null) { PythonName = Environment.GetEnvironmentVariable("PYTHON"); Log("Found python path {0} in PYTHON Environment Variable", PythonName); } // Check if the exe exists if (!System.IO.File.Exists(PythonName)) { Log("Either no python path can be found or it doesn't exist. Using python on PATH"); PythonName = Utils.IsRunningOnMono ? "python" : "python.exe"; } ProcessResult Result = ProcessManager.CreateProcess(PythonName, true, "html5server.log"); Result.ProcessObject.StartInfo.FileName = PythonName; Result.ProcessObject.StartInfo.UseShellExecute = false; Result.ProcessObject.StartInfo.RedirectStandardOutput = true; Result.ProcessObject.StartInfo.RedirectStandardInput = true; Result.ProcessObject.StartInfo.WorkingDirectory = directory; Result.ProcessObject.StartInfo.Arguments = input; Result.ProcessObject.Start(); Result.ProcessObject.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs e) { System.Console.WriteLine(e.Data); }; System.Console.WriteLine("Starting Browser Process"); // safari specific hack. string argument = url; if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono) argument = ""; ProcessResult ClientProcess = Run(browserPath, argument, null, ClientRunFlags | ERunOptions.NoWaitForExit); ClientProcess.ProcessObject.EnableRaisingEvents = true; ClientProcess.ProcessObject.Exited += delegate(System.Object o, System.EventArgs e) { System.Console.WriteLine("Browser Process Ended - Killing Webserver"); // send kill. Result.ProcessObject.StandardInput.Close(); Result.ProcessObject.Kill(); }; // safari needs a hack. // http://superuser.com/questions/689315/run-safari-from-terminal-with-given-url-address-without-open-command if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono) { // ClientProcess.ProcessObject.WaitForInputIdle (); Thread.Sleep (2000); Process.Start("/usr/bin/osascript"," -e 'tell application \"Safari\" to open location \"" + url + "\"'" ); } return ClientProcess; } System.Console.WriteLine("Browser Path " + browserPath); ProcessResult BrowserProcess = Run(browserPath, url, null, ClientRunFlags | ERunOptions.NoWaitForExit); return BrowserProcess; }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); bool ok = false; List <string> Devices; string browserPath = ""; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); if (ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5SDKSettings", "DeviceMap", out Devices)) { foreach (var Dev in Devices) { var Matched = Regex.Match(Dev, "\\(DeviceName=\"(.*)\",DevicePath=\\(FilePath=\"(.*)\"\\)\\)", RegexOptions.IgnoreCase); if (Matched.Success && Matched.Groups[1].ToString() == DeviceName) { browserPath = Matched.Groups[2].ToString(); ok = true; break; } } } if (!ok && HTML5SDKInfo.bAllowFallbackSDKSettings) { string DeviceSection; if (Utils.IsRunningOnMono) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); } if (!ok) { throw new System.Exception("Incorrect browser configuration in HTML5Engine.ini "); } // open the webpage Int32 ServerPort = 8000; ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort); string WorkingDirectory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) + ".html"; string args = "-m "; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { url = String.Format("http://127.0.0.1:{0}/{1}", ServerPort, url); args += String.Format("-h -s {0} ", ServerPort); } // Check HTML5LaunchHelper source for command line args var LowerBrowserPath = browserPath.ToLower(); args += String.Format("-b \"{0}\" -p \"{1}\" -w \"{2}\" ", browserPath, HTML5SDKInfo.PythonPath(), WorkingDirectory); args += url + " "; var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory(), "UE4_HTML5", "user"); if (LowerBrowserPath.Contains("chrome")) { args += String.Format("--user-data-dir=\"{0}\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome")); } else if (LowerBrowserPath.Contains("firefox")) { args += String.Format("-no-remote -profile \"{0}\" -jsconsole", Path.Combine(ProfileDirectory, "firefox")); } //else if (browserPath.Contains("Safari")) {} var LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"); ProcessResult BrowserProcess = Run(LaunchHelperPath, args, null, ClientRunFlags | ERunOptions.NoWaitForExit); return(BrowserProcess); }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); string DeviceSection; if (Utils.IsRunningOnMono) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } string browserPath; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); bool ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); if (!ok) { throw new System.Exception("Incorrect browser configuration in HTML5Engine.ini "); } // open the webpage string directory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) + ".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { var EmscriptenSettings = ReadEmscriptenSettings(); url = "http://127.0.0.1:8000/" + url; // this will be killed UBT instances dies. string input = String.Format(" -m SimpleHTTPServer 8000"); string PythonName = null; // Check the .emscripten file for a possible python path if (EmscriptenSettings.ContainsKey("PYTHON")) { PythonName = EmscriptenSettings["PYTHON"]; Log("Found python path {0} in emscripten file", PythonName); } // The AutoSDK defines this env var as part of its install. See setup.bat/unsetup.bat // If it's missing then just assume that python lives on the path if (PythonName == null && Environment.GetEnvironmentVariable("PYTHON") != null) { PythonName = Environment.GetEnvironmentVariable("PYTHON"); Log("Found python path {0} in PYTHON Environment Variable", PythonName); } // Check if the exe exists if (!System.IO.File.Exists(PythonName)) { Log("Either no python path can be found or it doesn't exist. Using python on PATH"); PythonName = Utils.IsRunningOnMono ? "python" : "python.exe"; } ProcessResult Result = ProcessManager.CreateProcess(PythonName, true, "html5server.log"); Result.ProcessObject.StartInfo.FileName = PythonName; Result.ProcessObject.StartInfo.UseShellExecute = false; Result.ProcessObject.StartInfo.RedirectStandardOutput = true; Result.ProcessObject.StartInfo.RedirectStandardInput = true; Result.ProcessObject.StartInfo.WorkingDirectory = directory; Result.ProcessObject.StartInfo.Arguments = input; Result.ProcessObject.Start(); Result.ProcessObject.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs e) { System.Console.WriteLine(e.Data); }; System.Console.WriteLine("Starting Browser Process"); // safari specific hack. string argument = url; if (browserPath.Contains("Safari") && Utils.IsRunningOnMono) { argument = ""; } ProcessResult ClientProcess = Run(browserPath, argument, null, ClientRunFlags | ERunOptions.NoWaitForExit); ClientProcess.ProcessObject.EnableRaisingEvents = true; ClientProcess.ProcessObject.Exited += delegate(System.Object o, System.EventArgs e) { System.Console.WriteLine("Browser Process Ended - Killing Webserver"); // send kill. Result.ProcessObject.StandardInput.Close(); Result.ProcessObject.Kill(); }; // safari needs a hack. // http://superuser.com/questions/689315/run-safari-from-terminal-with-given-url-address-without-open-command if (browserPath.Contains("Safari") && Utils.IsRunningOnMono) { // ClientProcess.ProcessObject.WaitForInputIdle (); Thread.Sleep(2000); Process.Start("/usr/bin/osascript", " -e 'tell application \"Safari\" to open location \"" + url + "\"'"); } return(ClientProcess); } System.Console.WriteLine("Browser Path " + browserPath); ProcessResult BrowserProcess = Run(browserPath, url, null, ClientRunFlags | ERunOptions.NoWaitForExit); return(BrowserProcess); }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); bool ok = false; List<string> Devices; string browserPath = ""; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); if (ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5SDKSettings", "DeviceMap", out Devices)) { foreach (var Dev in Devices) { var Matched = Regex.Match(Dev, "\\(DeviceName=\"(.*)\",DevicePath=\\(FilePath=\"(.*)\"\\)\\)", RegexOptions.IgnoreCase); if (Matched.Success && Matched.Groups[1].ToString() == DeviceName) { browserPath = Matched.Groups[2].ToString(); ok = true; break; } } } if (!ok && HTML5SDKInfo.bAllowFallbackSDKSettings) { string DeviceSection; if (Utils.IsRunningOnMono) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); } if (!ok) { throw new System.Exception("Incorrect browser configuration in HTML5Engine.ini "); } // open the webpage Int32 ServerPort = 8000; ConfigCache.GetInt32("/Script/HTML5PlatformEditor.HTML5TargetSettings", "DeployServerPort", out ServerPort); string WorkingDirectory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) +".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { url = String.Format("http://{2}:{0}/{1}", ServerPort, url, Environment.MachineName); } // Check HTML5LaunchHelper source for command line args var LowerBrowserPath = browserPath.ToLower(); var ProfileDirectory = Path.Combine(Utils.GetUserSettingDirectory(), "UE4_HTML5", "user"); string BrowserCommandline = url; if (LowerBrowserPath.Contains("chrome")) { BrowserCommandline += " " + String.Format("--user-data-dir=\"{0}\" --enable-logging --no-first-run", Path.Combine(ProfileDirectory, "chrome")); } else if (LowerBrowserPath.Contains("firefox")) { BrowserCommandline += " " + String.Format("-no-remote -profile \"{0}\"", Path.Combine(ProfileDirectory, "firefox")); } string LauncherArguments = string.Format( " -Browser=\"{0}\" + -BrowserCommandLine=\"{1}\" -ServerPort=\"{2}\" -ServerRoot=\"{3}\" ", new object[] { browserPath,BrowserCommandline,ServerPort,WorkingDirectory }); var LaunchHelperPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"); ProcessResult BrowserProcess = Run(LaunchHelperPath, LauncherArguments, null, ClientRunFlags | ERunOptions.NoWaitForExit); return BrowserProcess; }
public static bool GenerateIOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, string InEngineDir, string AppDirectory, UEDeployIOS InThis = null) { // generate the Info.plist for future use string BuildDirectory = ProjectDirectory + "/Build/IOS"; bool bSkipDefaultPNGs = false; string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/IOS"; string PListFile = IntermediateDirectory + "/" + GameName + "-Info.plist"; ProjectName = !String.IsNullOrEmpty(ProjectName) ? ProjectName : GameName; VersionUtilities.BuildDirectory = BuildDirectory; VersionUtilities.GameName = GameName; // read the old file string OldPListData = File.Exists(PListFile) ? File.ReadAllText(PListFile) : ""; // determine if there is a launch.xib string LaunchXib = InEngineDir + "/Build/IOS/Resources/Interface/LaunchScreen.xib"; if (File.Exists(BuildDirectory + "/Resources/Interface/LaunchScreen.xib")) { LaunchXib = BuildDirectory + "/Resources/Interface/LaunchScreen.xib"; } // get the settings from the ini file // plist replacements DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory); ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", DirRef); // orientations string SupportedOrientations = ""; bool bSupported = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsPortraitOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationPortrait</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsUpsideDownOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsLandscapeLeftOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsLandscapeRightOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n" : ""; // bundle display name string BundleDisplayName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleDisplayName", out BundleDisplayName); // bundle identifier string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); // bundle name string BundleName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleName", out BundleName); // disable https requirement bool bDisableHTTPS; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDisableHTTPS", out bDisableHTTPS); // short version string string BundleShortVersion; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "VersionInfo", out BundleShortVersion); // required capabilities string RequiredCaps = ""; if (InThis != null) { // required capabilities RequiredCaps += InThis.IOSPlatformContext.GetRequiredCapabilities(); } Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsOpenGLES2", out bSupported); RequiredCaps += bSupported ? "\t\t<string>opengles-2</string>\n" : ""; if (!bSupported) { Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsMetal", out bSupported); RequiredCaps += bSupported ? "\t\t<string>metal</string>\n" : ""; } // minimum iOS version string MinVersion; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": Log.TraceWarning("IOS 6 is no longer supported in UE4 as 4.11"); MinVersion = "7.0"; break; case "IOS_7": MinVersion = "7.0"; break; case "IOS_8": MinVersion = "8.0"; break; case "IOS_9": MinVersion = "9.0"; break; } } else { MinVersion = "7.0"; } // Get Facebook Support details bool bEnableFacebookSupport = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableFacebookSupport", out bEnableFacebookSupport); // Write the Facebook App ID if we need it. string FacebookAppID = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "FacebookAppID", out FacebookAppID); bEnableFacebookSupport = bEnableFacebookSupport && !string.IsNullOrWhiteSpace(FacebookAppID); // extra plist data string ExtraData = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalPlistData", out ExtraData); // generate the plist file StringBuilder Text = new StringBuilder(); Text.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); Text.AppendLine("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); Text.AppendLine("<plist version=\"1.0\">"); Text.AppendLine("<dict>"); Text.AppendLine("\t<key>CFBundleURLTypes</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleURLName</key>"); Text.AppendLine("\t\t\t<string>com.Epic.Unreal</string>"); Text.AppendLine("\t\t\t<key>CFBundleURLSchemes</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine(string.Format("\t\t\t\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName)); if (bEnableFacebookSupport) { // This is needed for facebook login to redirect back to the app after completion. Text.AppendLine(string.Format("\t\t\t\t<string>fb{0}</string>", FacebookAppID)); } Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleDevelopmentRegion</key>"); Text.AppendLine("\t<string>English</string>"); Text.AppendLine("\t<key>CFBundleDisplayName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleDisplayName, ProjectName))); Text.AppendLine("\t<key>CFBundleExecutable</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName)); Text.AppendLine("\t<key>CFBundleIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleInfoDictionaryVersion</key>"); Text.AppendLine("\t<string>6.0</string>"); Text.AppendLine("\t<key>CFBundleName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleName, ProjectName))); Text.AppendLine("\t<key>CFBundlePackageType</key>"); Text.AppendLine("\t<string>APPL</string>"); Text.AppendLine("\t<key>CFBundleSignature</key>"); Text.AppendLine("\t<string>????</string>"); Text.AppendLine("\t<key>CFBundleVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", VersionUtilities.UpdateBundleVersion(OldPListData))); Text.AppendLine("\t<key>CFBundleShortVersionString</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleShortVersion)); Text.AppendLine("\t<key>LSRequiresIPhoneOS</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIStatusBarHidden</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIRequiresFullScreen</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIViewControllerBasedStatusBarAppearance</key>"); Text.AppendLine("\t<false/>"); Text.AppendLine("\t<key>UISupportedInterfaceOrientations</key>"); Text.AppendLine("\t<array>"); foreach (string Line in SupportedOrientations.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>UIRequiredDeviceCapabilities</key>"); Text.AppendLine("\t<array>"); foreach (string Line in RequiredCaps.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleIcons</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon57.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); Text.AppendLine("\t\t\t<true/>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</dict>"); Text.AppendLine("\t<key>CFBundleIcons~ipad</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon50.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon72.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon76.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); Text.AppendLine("\t\t\t<true/>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</dict>"); if (File.Exists(LaunchXib)) { // TODO: compile the xib via remote tool Text.AppendLine("\t<key>UILaunchStoryboardName</key>"); Text.AppendLine("\t<string>LaunchScreen</string>"); bSkipDefaultPNGs = true; } else { // this is a temp way to inject the iphone 6 images without needing to upgrade everyone's plist // eventually we want to generate this based on what the user has set in the project settings string[] IPhoneConfigs = { "Default-IPhone6-Landscape", "Landscape", "{375, 667}", "8.0", "Default-IPhone6", "Portrait", "{375, 667}", "8.0", "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}", "8.0", "Default-IPhone6Plus-Portrait", "Portrait", "{414, 736}", "8.0", "Default", "Landscape", "{320, 480}", "7.0", "Default", "Portrait", "{320, 480}", "7.0", "Default-568h", "Landscape", "{320, 568}", "7.0", "Default-568h", "Portrait", "{320, 568}", "7.0", }; Text.AppendLine("\t<key>UILaunchImages~iphone</key>"); Text.AppendLine("\t<array>"); for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 4) { Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 3])); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 0])); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 1])); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 2])); Text.AppendLine("\t\t</dict>"); } // close it out Text.AppendLine("\t</array>"); // this is a temp way to inject the iPad Pro without needing to upgrade everyone's plist // eventually we want to generate this based on what the user has set in the project settings string[] IPadConfigs = { "Default-Landscape", "Landscape", "{768, 1024}", "7.0", "Default-Portrait", "Portrait", "{768, 1024}", "7.0", "Default-Landscape-1336", "Landscape", "{1024, 1366}", "9.0", "Default-Portrait-1336", "Portrait", "{1024, 1366}", "9.0", }; Text.AppendLine("\t<key>UILaunchImages~ipad</key>"); Text.AppendLine("\t<array>"); for (int ConfigIndex = 0; ConfigIndex < IPadConfigs.Length; ConfigIndex += 4) { Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 3])); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 0])); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 1])); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 2])); Text.AppendLine("\t\t</dict>"); } Text.AppendLine("\t</array>"); } Text.AppendLine("\t<key>CFBundleSupportedPlatforms</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<string>iPhoneOS</string>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>MinimumOSVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", MinVersion)); // disable exempt encryption Text.AppendLine("\t<key>ITSAppUsesNonExemptEncryption</key>"); Text.AppendLine("\t<false/>"); // disable HTTPS requirement if (bDisableHTTPS) { Text.AppendLine("\t<key>NSAppTransportSecurity</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>NSAllowsArbitraryLoads</key><true/>"); Text.AppendLine("\t\t</dict>"); } if (bEnableFacebookSupport) { Text.AppendLine("\t<key>FacebookAppID</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", FacebookAppID)); } if (!string.IsNullOrEmpty(ExtraData)) { ExtraData = ExtraData.Replace("\\n", "\n"); foreach (string Line in ExtraData.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine("\t" + Line); } } } Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); // Create the intermediate directory if needed if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } if (InThis != null && InThis.UPL != null) { // Allow UPL to modify the plist here XDocument XDoc; try { XDoc = XDocument.Parse(Text.ToString()); } catch (Exception e) { throw new BuildException("plist is invalid {0}\n{1}", e, Text.ToString()); } XDoc.DocumentType.InternalSubset = ""; InThis.UPL.ProcessPluginNode("None", "iosPListUpdates", "", ref XDoc); string result = XDoc.Declaration.ToString() + "\n" + XDoc.ToString().Replace("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"[]>", "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); File.WriteAllText(PListFile, result); } else { File.WriteAllText(PListFile, Text.ToString()); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { if (!Directory.Exists(AppDirectory)) { Directory.CreateDirectory(AppDirectory); } File.WriteAllText(AppDirectory + "/Info.plist", Text.ToString()); } return(bSkipDefaultPNGs); }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); string DeviceSection; if (Utils.IsRunningOnMono) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } string browserPath; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); bool ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); if (!ok) { throw new System.Exception("Incorrect browser configuration in HTML5Engine.ini "); } // open the webpage string directory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) + ".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { url = "http://127.0.0.1:8000/" + url; // this will be killed UBT instances dies. string input = String.Format(" -m SimpleHTTPServer 8000"); string PythonPath = HTML5SDKInfo.PythonPath(); ProcessResult Result = ProcessManager.CreateProcess(PythonPath, true, "html5server.log"); Result.ProcessObject.StartInfo.FileName = PythonPath; Result.ProcessObject.StartInfo.UseShellExecute = false; Result.ProcessObject.StartInfo.RedirectStandardOutput = true; Result.ProcessObject.StartInfo.RedirectStandardInput = true; Result.ProcessObject.StartInfo.WorkingDirectory = directory; Result.ProcessObject.StartInfo.Arguments = input; Result.ProcessObject.Start(); Result.ProcessObject.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs e) { System.Console.WriteLine(e.Data); }; System.Console.WriteLine("Starting Browser Process"); // safari specific hack. string argument = url; if (browserPath.Contains("Safari") && Utils.IsRunningOnMono) { argument = ""; } // Chrome issue. Firefox may work like this in the future bool bBrowserWillSpawnProcess = browserPath.Contains("chrome") || (browserPath.Contains("Google Chrome") && Utils.IsRunningOnMono); ProcessResult SubProcess = null; ProcessResult ClientProcess = Run(browserPath, argument, null, ClientRunFlags | ERunOptions.NoWaitForExit); var ProcStartTime = ClientProcess.ProcessObject.StartTime; var ProcName = ClientProcess.ProcessObject.ProcessName; ClientProcess.ProcessObject.EnableRaisingEvents = true; ClientProcess.ProcessObject.Exited += delegate(System.Object o, System.EventArgs e) { System.Console.WriteLine("Browser Process Ended (PID={0})", ClientProcess.ProcessObject.Id); var bFoundChildProcess = true; if (bBrowserWillSpawnProcess) { bFoundChildProcess = false; // Chrome spawns a process from the tab it opens and then lets the process we spawned die, so // catch that process and attach to that instead. var CurrentProcesses = Process.GetProcesses(); foreach (var item in CurrentProcesses) { if (item.Id != ClientProcess.ProcessObject.Id && item.ProcessName == ProcName && item.StartTime >= ProcStartTime && item.StartTime <= ClientProcess.ProcessObject.ExitTime) { var PID = item.Id; System.Console.WriteLine("Found Process {0} with PID {1} which started at {2}. Waiting on that process to end.", item.ProcessName, item.Id, item.StartTime.ToString()); SubProcess = new ProcessResult(item.ProcessName, item, true, item.ProcessName); item.EnableRaisingEvents = true; item.Exited += delegate(System.Object o2, System.EventArgs e2) { System.Console.WriteLine("Browser Process Ended (PID={0}) - Killing Webserver", PID); Result.ProcessObject.StandardInput.Close(); Result.ProcessObject.Kill(); }; bFoundChildProcess = true; } } } if (!bFoundChildProcess) { System.Console.WriteLine("- Killing Webserver", ClientProcess.ProcessObject.Id); Result.ProcessObject.StandardInput.Close(); Result.ProcessObject.Kill(); } }; if (bBrowserWillSpawnProcess) { //Wait for it to do so... ClientProcess.ProcessObject.WaitForExit(); ClientProcess = SubProcess; } // safari needs a hack. // http://superuser.com/questions/689315/run-safari-from-terminal-with-given-url-address-without-open-command if (browserPath.Contains("Safari") && Utils.IsRunningOnMono) { // ClientProcess.ProcessObject.WaitForInputIdle (); Thread.Sleep(2000); Process.Start("/usr/bin/osascript", " -e 'tell application \"Safari\" to open location \"" + url + "\"'"); } return(ClientProcess); } System.Console.WriteLine("Browser Path " + browserPath); ProcessResult BrowserProcess = Run(browserPath, url, null, ClientRunFlags | ERunOptions.NoWaitForExit); return(BrowserProcess); }
public override void SetUpProjectEnvironment(UnrealTargetConfiguration Configuration, TargetInfo Target = null) { if (!bInitializedProject) { base.SetUpProjectEnvironment(Configuration, Target); // update the configuration based on the project file // look in ini settings for what platforms to compile for ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(Platform, "Engine", DirectoryReference.FromFile(ProjectFile)); string MinVersion = "IOS_8"; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": Log.TraceWarningOnce("IOS 6 is no longer supported in UE4 as 4.11"); RunTimeIOSVersion = "8.0"; break; case "IOS_7": Log.TraceWarningOnce("IOS 7 is no longer supported in UE4 as 4.14"); RunTimeIOSVersion = "8.0"; break; case "IOS_8": RunTimeIOSVersion = "8.0"; break; case "IOS_9": RunTimeIOSVersion = "9.0"; break; case "IOS_10": RunTimeIOSVersion = "10.0"; break; } } bool biPhoneAllowed = true; bool biPadAllowed = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPhone", out biPhoneAllowed); Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPad", out biPadAllowed); if (biPhoneAllowed && biPadAllowed) { RunTimeIOSDevices = "1,2"; } else if (biPadAllowed) { RunTimeIOSDevices = "2"; } else if (biPhoneAllowed) { RunTimeIOSDevices = "1"; } ProjectArches = new List <string>(); bool bBuild = true; if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); } NonShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { NonShippingArchitectures += "," + ProjectArches[Index]; } ProjectArches.Clear(); if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); ProjectArches.Add("arm64"); } ShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { ShippingArchitectures += "," + ProjectArches[Index]; } // determine if we need to generate the dsym Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGeneratedSYMFile", out BuildConfiguration.bGeneratedSYMFile); Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGeneratedSYMBundle", out BuildConfiguration.bGeneratedSYMBundle); // determie if bitcode should be generated for the shipping code Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForBitcode", out bShipForBitcode); // @todo tvos: We probably want to handle TVOS versions here Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalLinkerFlags", out AdditionalLinkerFlags); Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalShippingLinkerFlags", out AdditionalShippingLinkerFlags); Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MobileProvision", out MobileProvision); Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SigningCertificate", out SigningCertificate); // bundle identifier Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); bInitializedProject = true; } ProvisionData Data = new ProvisionData(); string BundleId = BundleIdentifier.Replace("[PROJECT_NAME]", ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game")).Replace("_", ""); bool bIsTVOS = GetCodesignPlatformName() == "appletvos"; if (!ProvisionCache.ContainsKey(BundleId + " " + bIsTVOS.ToString() + " " + bForDistribtion.ToString())) { Certificate = SigningCertificate; Provision = MobileProvision; if (!string.IsNullOrEmpty(SigningCertificate)) { // verify the certificate Process IPPProcess = new Process(); if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bForDistribtion ? " -distribution" : ""); IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString(); IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh"; IPPProcess.StartInfo.Arguments = IPPCmd; IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); } else { string IPPCmd = "certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bForDistribtion ? " -distribution" : ""); IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString(); IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe"; IPPProcess.StartInfo.Arguments = IPPCmd; IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); } Utils.RunLocalProcess(IPPProcess); } else { Certificate = bForDistribtion ? "iPhone Distribution" : "iPhone Developer"; bHaveCertificate = true; } if (string.IsNullOrEmpty(MobileProvision) || // no provision specified !File.Exists((BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac ? (Environment.GetEnvironmentVariable("HOME") + "/Library/MobileDevice/Provisioning Profiles/") : (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Apple Computer/MobileDevice/Provisioning Profiles/")) + MobileProvision) || // file doesn't exist !bHaveCertificate) // certificate doesn't exist { Certificate = ""; Provision = ""; Log.TraceLog("Provision not specified or not found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", searching for compatible match..."); Process IPPProcess = new Process(); if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : ""); IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString(); IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh"; IPPProcess.StartInfo.Arguments = IPPCmd; IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); } else { string IPPCmd = "signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : ""); IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString(); IPPProcess.StartInfo.FileName = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe"; IPPProcess.StartInfo.Arguments = IPPCmd; IPPProcess.OutputDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); IPPProcess.ErrorDataReceived += new DataReceivedEventHandler(IPPDataReceivedHandler); } Utils.RunLocalProcess(IPPProcess); Log.TraceLog("Provision found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", Provision: " + Provision + " Certificate: " + Certificate); } // add to the dictionary Data.MobileProvision = Provision; Data.Certificate = Certificate.Replace("\"", ""); // read the provision to get the UUID string filename = (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac ? (Environment.GetEnvironmentVariable("HOME") + "/Library/MobileDevice/Provisioning Profiles/") : (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Apple Computer/MobileDevice/Provisioning Profiles/")) + Data.MobileProvision; if (File.Exists(filename)) { string AllText = File.ReadAllText(filename); int idx = AllText.IndexOf("<key>UUID</key>"); if (idx > 0) { idx = AllText.IndexOf("<string>", idx); if (idx > 0) { idx += "<string>".Length; Data.UUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx); } } idx = AllText.IndexOf("<key>com.apple.developer.team-identifier</key>"); if (idx > 0) { idx = AllText.IndexOf("<string>", idx); if (idx > 0) { idx += "<string>".Length; Data.TeamUUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx); } } } else { Log.TraceLog("No matching provision file was discovered. Please ensure you have a compatible provision installed."); } ProvisionCache.Add(BundleId + " " + bIsTVOS.ToString() + " " + bForDistribtion.ToString(), Data); } else { Data = ProvisionCache[BundleId + " " + bIsTVOS.ToString() + " " + bForDistribtion.ToString()]; } MobileProvision = Data.MobileProvision; SigningCertificate = Data.Certificate; MobileProvisionUUID = Data.UUID; TeamUUID = Data.TeamUUID; }
public static bool GenerateTVOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, string InEngineDir, string AppDirectory, UEDeployTVOS InThis = null) { // @todo tvos: THIS! // generate the Info.plist for future use string BuildDirectory = ProjectDirectory + "/Build/TVOS"; bool bSkipDefaultPNGs = false; string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/TVOS"; string PListFile = IntermediateDirectory + "/" + GameName + "-Info.plist"; // @todo tvos: This is really nasty - both IOS and TVOS are setting static vars VersionUtilities.BuildDirectory = BuildDirectory; VersionUtilities.GameName = GameName; // read the old file string OldPListData = File.Exists(PListFile) ? File.ReadAllText(PListFile) : ""; // determine if there is a launch.xib string LaunchXib = InEngineDir + "/Build/IOS/Resources/Interface/LaunchScreen.xib"; if (File.Exists(BuildDirectory + "/Resources/Interface/LaunchScreen.xib")) { LaunchXib = BuildDirectory + "/Resources/Interface/LaunchScreen.xib"; } // get the settings from the ini file // plist replacements // @todo tvos: Are we going to make TVOS specific .ini files? ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", bIsUE4Game? null : new DirectoryReference(ProjectDirectory)); // bundle display name string BundleDisplayName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleDisplayName", out BundleDisplayName); // bundle identifier string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); // bundle name string BundleName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleName", out BundleName); // short version string string BundleShortVersion; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "VersionInfo", out BundleShortVersion); // required capabilities string RequiredCaps = "\t\t<string>arm64</string>\n"; // minimum iOS version string MinVersion; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumTVOSVersion", out MinVersion)) { switch (MinVersion) { case "TVOS_9": MinVersion = "9.0"; break; } } else { MinVersion = "9.0"; } // extra plist data string ExtraData = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalPlistData", out ExtraData); // create the final display name, including converting all entities for XML use string FinalDisplayName = BundleDisplayName.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""); FinalDisplayName = FinalDisplayName.Replace("&", "&"); FinalDisplayName = FinalDisplayName.Replace("\"", """); FinalDisplayName = FinalDisplayName.Replace("\'", "'"); FinalDisplayName = FinalDisplayName.Replace("<", "<"); FinalDisplayName = FinalDisplayName.Replace(">", ">"); // generate the plist file StringBuilder Text = new StringBuilder(); Text.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); Text.AppendLine("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); Text.AppendLine("<plist version=\"1.0\">"); Text.AppendLine("<dict>"); Text.AppendLine("\t<key>CFBundleDevelopmentRegion</key>"); Text.AppendLine("\t<string>en</string>"); Text.AppendLine("\t<key>CFBundleDisplayName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleDisplayName, ProjectName))); Text.AppendLine("\t<key>CFBundleExecutable</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName)); Text.AppendLine("\t<key>CFBundleIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleInfoDictionaryVersion</key>"); Text.AppendLine("\t<string>6.0</string>"); Text.AppendLine("\t<key>CFBundleName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleName, ProjectName))); Text.AppendLine("\t<key>CFBundlePackageType</key>"); Text.AppendLine("\t<string>APPL</string>"); Text.AppendLine("\t<key>CFBundleSignature</key>"); Text.AppendLine("\t<string>????</string>"); Text.AppendLine("\t<key>CFBundleVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", VersionUtilities.UpdateBundleVersion(OldPListData))); Text.AppendLine("\t<key>CFBundleShortVersionString</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleShortVersion)); Text.AppendLine("\t<key>LSRequiresIPhoneOS</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIRequiredDeviceCapabilities</key>"); Text.AppendLine("\t<array>"); foreach (string Line in RequiredCaps.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>TVTopShelfImage</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>TVTopShelfPrimaryImage</key>"); Text.AppendLine("\t\t<string>TopShelf</string>"); Text.AppendLine("\t</dict>"); Text.AppendLine("\t<key>UILaunchImages</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine("\t\t\t<string>{1920, 1080}</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine("\t\t\t<string>LaunchImage</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine("\t\t\t<string>9.0</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine("\t\t\t<string>Landscape</string>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleIcons</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<string>AppIconSmall</string>"); Text.AppendLine("\t</dict>"); /* Text.AppendLine("\t<key>CFBundleIcons</key>"); * Text.AppendLine("\t<dict>"); * Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); * Text.AppendLine("\t\t\t<array>"); * Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon57.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t</array>"); * Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); * Text.AppendLine("\t\t\t<true/>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t</dict>"); * Text.AppendLine("\t<key>CFBundleIcons~ipad</key>"); * Text.AppendLine("\t<dict>"); * Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); * Text.AppendLine("\t\t\t<array>"); * Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon50.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon72.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon76.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t</array>"); * Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); * Text.AppendLine("\t\t\t<true/>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t</dict>"); * if (File.Exists(LaunchXib)) * { * // TODO: compile the xib via remote tool * Text.AppendLine("\t<key>UILaunchStoryboardName</key>"); * Text.AppendLine("\t<string>LaunchScreen</string>"); * bSkipDefaultPNGs = true; * } * else * { * // this is a temp way to inject the iphone 6 images without needing to upgrade everyone's plist * // eventually we want to generate this based on what the user has set in the project settings * string[] IPhoneConfigs = * { * "Default-IPhone6", "Landscape", "{375, 667}", * "Default-IPhone6", "Portrait", "{375, 667}", * "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}", * "Default-IPhone6Plus-Portrait", "Portrait", "{414, 736}", * "Default", "Landscape", "{320, 480}", * "Default", "Portrait", "{320, 480}", * "Default-568h", "Landscape", "{320, 568}", * "Default-568h", "Portrait", "{320, 568}", * }; * * Text.AppendLine("\t<key>UILaunchImages~iphone</key>"); * Text.AppendLine("\t<array>"); * for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 3) * { * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>8.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 0])); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 1])); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 2])); * Text.AppendLine("\t\t</dict>"); * } * * // close it out * Text.AppendLine("\t</array>"); * } * Text.AppendLine("\t<key>UILaunchImages~ipad</key>"); * Text.AppendLine("\t<array>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>7.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine("\t\t\t<string>Default-Landscape</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine("\t\t\t<string>Landscape</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>7.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine("\t\t\t<string>Default-Portrait</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine("\t\t\t<string>Portrait</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t</array>”); * Text.AppendLine("\t<key>CFBundleSupportedPlatforms</key>"); * Text.AppendLine("\t<array>"); * Text.AppendLine("\t\t<string>iPhoneOS</string>"); * Text.AppendLine("\t</array>"); * Text.AppendLine("\t<key>MinimumOSVersion</key>"); * Text.AppendLine(string.Format("\t<string>{0}</string>", MinVersion)); * if (!string.IsNullOrEmpty(ExtraData)) * { * ExtraData = ExtraData.Replace("\\n", "\n"); * foreach (string Line in ExtraData.Split("\r\n".ToCharArray())) * { * if (!string.IsNullOrWhiteSpace(Line)) * { * Text.AppendLine("\t" + Line); * } * } * }*/ Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); // Create the intermediate directory if needed if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } if (InThis != null && InThis.UPL != null) { // Allow UPL to modify the plist here XDocument XDoc; try { XDoc = XDocument.Parse(Text.ToString()); } catch (Exception e) { throw new BuildException("plist is invalid {0}\n{1}", e, Text.ToString()); } XDoc.DocumentType.InternalSubset = ""; InThis.UPL.ProcessPluginNode("None", "iosPListUpdates", "", ref XDoc); string result = XDoc.Declaration.ToString() + "\n" + XDoc.ToString().Replace("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"[]>", "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); File.WriteAllText(PListFile, result); } else { File.WriteAllText(PListFile, Text.ToString()); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { if (!Directory.Exists(AppDirectory)) { Directory.CreateDirectory(AppDirectory); } File.WriteAllText(AppDirectory + "/Info.plist", Text.ToString()); } return(bSkipDefaultPNGs); }
public override void SetUpProjectEnvironment(UnrealTargetPlatform InPlatform) { if (!bInitializedProject) { base.SetUpProjectEnvironment(InPlatform); // update the configuration based on the project file // look in ini settings for what platforms to compile for ConfigCacheIni Ini = new ConfigCacheIni(InPlatform, "Engine", UnrealBuildTool.GetUProjectPath()); string MinVersion = "IOS_6"; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": RunTimeIOSVersion = "6.1"; break; case "IOS_7": RunTimeIOSVersion = "7.0"; break; case "IOS_8": RunTimeIOSVersion = "8.0"; break; } } bool biPhoneAllowed = true; bool biPadAllowed = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPhone", out biPhoneAllowed); Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPad", out biPadAllowed); if (biPhoneAllowed && biPadAllowed) { RunTimeIOSDevices = "1,2"; } else if (biPadAllowed) { RunTimeIOSDevices = "2"; } else if (biPhoneAllowed) { RunTimeIOSDevices = "1"; } List <string> ProjectArches = new List <string>(); bool bBuild = true; if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); } NonShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { NonShippingArchitectures += "," + ProjectArches[Index]; } ProjectArches.Clear(); if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7", out bBuild) && bBuild) { ProjectArches.Add("armv7"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArm64", out bBuild) && bBuild) { ProjectArches.Add("arm64"); } if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7S", out bBuild) && bBuild) { ProjectArches.Add("armv7s"); } // force armv7 if something went wrong if (ProjectArches.Count == 0) { ProjectArches.Add("armv7"); ProjectArches.Add("arm64"); } ShippingArchitectures = ProjectArches[0]; for (int Index = 1; Index < ProjectArches.Count; ++Index) { ShippingArchitectures += "," + ProjectArches[Index]; } // determine if we need to generate the dsym Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGenerateSYMFile", out BuildConfiguration.bGeneratedSYMFile); bInitializedProject = true; } }
public static string EmscriptenSDKPath() { EnsureConfigCacheIsReady(); // Search the ini file for Emscripten root first string EmscriptenRoot; string EMCCPath; if (ConfigCache.GetString("/Script/HTML5PlatformEditor.HTML5SDKSettings", "EmscriptenRoot", out EmscriptenRoot)) { string SDKPathString = null; string VersionString = null; var Index = EmscriptenRoot.IndexOf("SDKPath="); if (Index != -1) { Index += 9; var Index2 = EmscriptenRoot.IndexOf("\"", Index); if (Index2 != -1) { SDKPathString = EmscriptenRoot.Substring(Index, Index2 - Index); } } Index = EmscriptenRoot.IndexOf("EmscriptenVersion="); if (Index != -1) { Index += 19; var Index2 = EmscriptenRoot.IndexOf("\"", Index); if (Index2 != -1) { VersionString = EmscriptenRoot.Substring(Index, Index2 - Index); } } if (!string.IsNullOrEmpty(SDKPathString) && !string.IsNullOrEmpty(VersionString)) { var SDKVersions = GetInstalledVersions(SDKPathString); if (VersionString == "-1.-1.-1" && SDKVersions.Count > 0) { var Ver = SDKVersions[SDKVersions.Count - 1]; if (System.IO.Directory.Exists(Ver.Directory)) { return(Ver.Directory); } } var RequiredVersion = System.Version.Parse(VersionString); foreach (var i in SDKVersions) { if (i.Version == RequiredVersion && System.IO.Directory.Exists(i.Directory)) { return(i.Directory); } } } } // Old Method if (bAllowFallbackSDKSettings) { bool ok = ConfigCache.GetString("HTML5SDKPaths", "Emscripten", out EMCCPath); if (ok && System.IO.Directory.Exists(EMCCPath)) { return(EMCCPath); } // Older method used platform name string PlatformName = ""; if (!Utils.IsRunningOnMono) { PlatformName = "Windows"; } else { PlatformName = "Mac"; } ok = ConfigCache.GetString("HTML5SDKPaths", PlatformName, out EMCCPath); if (ok && System.IO.Directory.Exists(EMCCPath)) { return(EMCCPath); } // try to find SDK Location from env. if (Environment.GetEnvironmentVariable("EMSCRIPTEN") != null && System.IO.Directory.Exists(Environment.GetEnvironmentVariable("EMSCRIPTEN")) ) { return(Environment.GetEnvironmentVariable("EMSCRIPTEN")); } } return(""); }
public override ProcessResult RunClient(ERunOptions ClientRunFlags, string ClientApp, string ClientCmdLine, ProjectParams Params) { // look for browser var ConfigCache = new UnrealBuildTool.ConfigCacheIni(UnrealTargetPlatform.HTML5, "Engine", Path.GetDirectoryName(Params.RawProjectPath), CombinePaths(CmdEnv.LocalRoot, "Engine")); string DeviceSection; if ( Utils.IsRunningOnMono ) { DeviceSection = "HTML5DevicesMac"; } else { DeviceSection = "HTML5DevicesWindows"; } string browserPath; string DeviceName = Params.Device.Split('@')[1]; DeviceName = DeviceName.Substring(0, DeviceName.LastIndexOf(" on ")); bool ok = ConfigCache.GetString(DeviceSection, DeviceName, out browserPath); if (!ok) throw new System.Exception ("Incorrect browser configuration in HTML5Engine.ini "); // open the webpage string directory = Path.GetDirectoryName(ClientApp); string url = Path.GetFileName(ClientApp) +".html"; // Are we running via cook on the fly server? // find our http url - This is awkward because RunClient doesn't have real information that NFS is running or not. bool IsCookOnTheFly = false; // 9/24/2014 @fixme - All this is convoluted, clean up. // looks like cookonthefly commandline stopped adding protocol or the port :/ hard coding to DEFAULT_TCP_FILE_SERVING_PORT+1 (DEFAULT_HTTP_FILE_SERVING_PORT) // This will fail if the NFS server is started with a different port - we need to modify driver .cs script to pass in IP/Port data correctly. if (ClientCmdLine.Contains("filehostip")) { IsCookOnTheFly = true; url = "http://127.0.0.1:41898/" + url; } if (IsCookOnTheFly) { url += "?cookonthefly=true"; } else { url = "http://127.0.0.1:8000/" + url; // this will be killed UBT instances dies. string input = String.Format(" -m SimpleHTTPServer 8000"); string PythonPath = HTML5SDKInfo.PythonPath(); ProcessResult Result = ProcessManager.CreateProcess(PythonPath, true, "html5server.log"); Result.ProcessObject.StartInfo.FileName = PythonPath; Result.ProcessObject.StartInfo.UseShellExecute = false; Result.ProcessObject.StartInfo.RedirectStandardOutput = true; Result.ProcessObject.StartInfo.RedirectStandardInput = true; Result.ProcessObject.StartInfo.WorkingDirectory = directory; Result.ProcessObject.StartInfo.Arguments = input; Result.ProcessObject.Start(); Result.ProcessObject.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs e) { System.Console.WriteLine(e.Data); }; System.Console.WriteLine("Starting Browser Process"); // safari specific hack. string argument = url; if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono) argument = ""; // Chrome issue. Firefox may work like this in the future bool bBrowserWillSpawnProcess = browserPath.Contains("chrome") || (browserPath.Contains("Google Chrome") && Utils.IsRunningOnMono); ProcessResult SubProcess = null; ProcessResult ClientProcess = Run(browserPath, argument, null, ClientRunFlags | ERunOptions.NoWaitForExit); var ProcStartTime = ClientProcess.ProcessObject.StartTime; var ProcName = ClientProcess.ProcessObject.ProcessName; ClientProcess.ProcessObject.EnableRaisingEvents = true; ClientProcess.ProcessObject.Exited += delegate(System.Object o, System.EventArgs e) { System.Console.WriteLine("Browser Process Ended (PID={0})", ClientProcess.ProcessObject.Id); var bFoundChildProcess = false; if (bBrowserWillSpawnProcess) { // Chrome spawns a process from the tab it opens and then lets the process we spawned die, so // catch that process and attach to that instead. var CurrentProcesses = Process.GetProcesses(); foreach (var item in CurrentProcesses) { if (item.Id != ClientProcess.ProcessObject.Id && item.ProcessName == ProcName && item.StartTime >= ProcStartTime && item.StartTime <= ClientProcess.ProcessObject.ExitTime) { var PID = item.Id; System.Console.WriteLine("Found Process {0} with PID {1} which started at {2}. Waiting on that process to end.", item.ProcessName, item.Id, item.StartTime.ToString()); SubProcess = new ProcessResult(item.ProcessName, item, true, item.ProcessName); item.EnableRaisingEvents = true; item.Exited += delegate(System.Object o2, System.EventArgs e2) { System.Console.WriteLine("Browser Process Ended (PID={0}) - Killing Webserver", PID); Result.ProcessObject.StandardInput.Close(); Result.ProcessObject.Kill(); }; bFoundChildProcess = true; } } } if (!bFoundChildProcess) { System.Console.WriteLine("- Killing Webserver PID({0})", Result.ProcessObject.Id); Result.ProcessObject.StandardInput.Close(); Result.ProcessObject.Kill(); } }; if (bBrowserWillSpawnProcess) { //Wait for it to do so... ClientProcess.ProcessObject.WaitForExit(); ClientProcess = SubProcess; } // safari needs a hack. // http://superuser.com/questions/689315/run-safari-from-terminal-with-given-url-address-without-open-command if (browserPath.Contains ("Safari") && Utils.IsRunningOnMono) { // ClientProcess.ProcessObject.WaitForInputIdle (); Thread.Sleep (2000); Process.Start("/usr/bin/osascript"," -e 'tell application \"Safari\" to open location \"" + url + "\"'" ); } return ClientProcess; } System.Console.WriteLine("Browser Path " + browserPath); ProcessResult BrowserProcess = Run(browserPath, url, null, ClientRunFlags | ERunOptions.NoWaitForExit); return BrowserProcess; }