Пример #1
0
        /// <summary>
        /// Creates an entitlements blob string from the entitlements structure in the mobile provision, merging in an on disk file if it is present.
        /// </summary>
        private string BuildEntitlementString(string CFBundleIdentifier)
        {
            // Load the base entitlements string from the mobile provision
            string ProvisionEntitlements = Provision.GetEntitlementsString(CFBundleIdentifier);

            // See if there is an override entitlements file on disk
            string UserOverridesEntitlementsFilename = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".entitlements");

            if (File.Exists(UserOverridesEntitlementsFilename))
            {
                // Merge in the entitlements from the on disk file as overrides
                Program.Log("Merging override entitlements from {0} into provision specified entitlements", Path.GetFileName(UserOverridesEntitlementsFilename));

                Utilities.PListHelper Merger = new Utilities.PListHelper(ProvisionEntitlements);
                string Overrides             = File.ReadAllText(UserOverridesEntitlementsFilename, Encoding.UTF8);
                Merger.MergePlistIn(Overrides);

                return(Merger.SaveToString());
            }
            else
            {
                // The ones from the mobile provision need no overrides
                return(ProvisionEntitlements);
            }
        }
Пример #2
0
        static bool FindMobileProvision(string BundleIdentifier, out string OutFileName)
        {
            bool   bNameMatch;
            string ProvisionWithPrefix = MobileProvision.FindCompatibleProvision(BundleIdentifier, out bNameMatch, true, true, false);

            if (!File.Exists(ProvisionWithPrefix))
            {
                ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".mobileprovision");
                if (!File.Exists(ProvisionWithPrefix))
                {
                    ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory + "/NotForLicensees/", Program.GameName + ".mobileprovision");
                    if (!File.Exists(ProvisionWithPrefix))
                    {
                        ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory, "UE4Game.mobileprovision");
                        if (!File.Exists(ProvisionWithPrefix))
                        {
                            ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory + "/NotForLicensees/", "UE4Game.mobileprovision");
                            if (!File.Exists(ProvisionWithPrefix))
                            {
                                OutFileName = null;
                                return(false);
                            }
                        }
                    }
                }
            }

            OutFileName = ProvisionWithPrefix;
            return(true);
        }
Пример #3
0
 /// <summary>
 /// Returns the full path for the stub IPA, following the signing prefix resolution rules
 /// </summary>
 public static string GetIPAPathForReading(string FileSuffix)
 {
     if (Program.GameConfiguration == "Development")
     {
         return(FileOperations.FindPrefixedFile(Config.BinariesDirectory, Program.GameName + Program.Architecture + FileSuffix));
     }
     else
     {
         return(FileOperations.FindPrefixedFile(Config.BinariesDirectory, Program.GameName + "-" + Config.OSString + "-" + Program.GameConfiguration + Program.Architecture + FileSuffix));
     }
 }
Пример #4
0
        static public string GetPrecompileSourcePListFilename()
        {
            // Check for a premade one
            string SourceName = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + "-Info.plist");

            if (!File.Exists(SourceName))
            {
                // fallback to the shared one
                SourceName = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory, "UE4Game-Info.plist");

                if (!File.Exists(SourceName))
                {
                    Program.Log("Failed to find " + Program.GameName + "-Info.plist. Please create new .plist or copy a base .plist from a provided game sample.");
                }
            }

            return(SourceName);
        }
Пример #5
0
        /// <summary>
        /// Copy the files always needed (even in a stub IPA)
        /// </summary>
        static public void CopyFilesNeededForMakeApp()
        {
            // Copy Info.plist over (modifiying it as needed)
            string SourcePListFilename = Utilities.GetPrecompileSourcePListFilename();

            Utilities.PListHelper Info = Utilities.PListHelper.CreateFromFile(SourcePListFilename);

            // Edit the plist
            CookTime.UpdateVersion(Info);

            // Write out the <GameName>-Info.plist file to the xcode staging directory
            string TargetPListFilename = Path.Combine(Config.PCXcodeStagingDir, Program.GameName + "-Info.plist");

            Directory.CreateDirectory(Path.GetDirectoryName(TargetPListFilename));
            string OutString = Info.SaveToString();

            OutString = OutString.Replace("${EXECUTABLE_NAME}", Program.GameName);
            OutString = OutString.Replace("${BUNDLE_IDENTIFIER}", Program.GameName.Replace("_", ""));

            // 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}",
                "Default-IPhoneX-Landscape",     "Landscape", "{375, 812}",
                "Default-IPhoneX-Portrait",      "Portrait",  "{375, 812}",
            };

            StringBuilder NewLaunchImagesString = new StringBuilder("<key>UILaunchImages~iphone</key>\n\t\t<array>\n");

            for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 3)
            {
                NewLaunchImagesString.Append("\t\t\t<dict>\n");
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageMinimumOSVersion</key>\n");
                NewLaunchImagesString.Append("\t\t\t\t<string>8.0</string>\n");
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageName</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 0]);
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageOrientation</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 1]);
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageSize</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 2]);
                NewLaunchImagesString.Append("\t\t\t</dict>\n");
            }

            // close it out
            NewLaunchImagesString.Append("\t\t\t</array>\n\t\t<key>UILaunchImages~ipad</key>");
            OutString = OutString.Replace("<key>UILaunchImages~ipad</key>", NewLaunchImagesString.ToString());

            byte[] RawInfoPList = Encoding.UTF8.GetBytes(OutString);
            File.WriteAllBytes(TargetPListFilename, RawInfoPList);

            Program.Log("Updating .plist: {0} --> {1}", SourcePListFilename, TargetPListFilename);

            // look for an entitlements file (optional)
            string SourceEntitlements = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".entitlements");

            // set where to make the entitlements file (
            string TargetEntitlements = Path.Combine(Config.PCXcodeStagingDir, Program.GameName + ".entitlements");

            if (File.Exists(SourceEntitlements))
            {
                FileOperations.CopyRequiredFile(SourceEntitlements, TargetEntitlements);
            }
            else
            {
                // we need to have something so Xcode will compile, so we just set the get-task-allow, since we know the value,
                // which is based on distribution or not (true means debuggable)
                File.WriteAllText(TargetEntitlements, string.Format("<plist><dict><key>get-task-allow</key><{0}/></dict></plist>",
                                                                    Config.bForDistribution ? "false" : "true"));
            }

            // Copy the mobile provision file over
            string CFBundleIdentifier = null;

            Info.GetString("CFBundleIdentifier", out CFBundleIdentifier);
            bool   bNameMatch;
            string ProvisionWithPrefix = MobileProvision.FindCompatibleProvision(CFBundleIdentifier, out bNameMatch);

            if (!File.Exists(ProvisionWithPrefix))
            {
                ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".mobileprovision");
                if (!File.Exists(ProvisionWithPrefix))
                {
                    ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory + "/NotForLicensees/", Program.GameName + ".mobileprovision");
                    if (!File.Exists(ProvisionWithPrefix))
                    {
                        ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory, "UE4Game.mobileprovision");
                        if (!File.Exists(ProvisionWithPrefix))
                        {
                            ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory + "/NotForLicensees/", "UE4Game.mobileprovision");
                        }
                    }
                }
            }
            string FinalMobileProvisionFilename = Path.Combine(Config.PCXcodeStagingDir, MacMobileProvisionFilename);

            FileOperations.CopyRequiredFile(ProvisionWithPrefix, FinalMobileProvisionFilename);

            // make sure this .mobileprovision file is newer than any other .mobileprovision file on the Mac (this file gets multiple games named the same file,
            // so the time stamp checking can fail when moving between games, a la the buildmachines!)
            File.SetLastWriteTime(FinalMobileProvisionFilename, DateTime.UtcNow);
            string ProjectFile = Config.RootRelativePath + @"Engine\Intermediate\ProjectFiles\UE4.xcodeproj\project.pbxproj";

            if (Program.GameName != "UE4Game")
            {
                ProjectFile = Path.GetDirectoryName(Config.IntermediateDirectory) + @"\ProjectFiles\" + Program.GameName + @".xcodeproj\project.pbxproj";
            }
            FileOperations.CopyRequiredFile(ProjectFile, Path.Combine(Config.PCXcodeStagingDir, @"project.pbxproj.datecheck"));

            // copy the signing certificate over
            // export the signing certificate to a file
            MobileProvision Provision   = MobileProvisionParser.ParseFile(ProvisionWithPrefix);
            var             Certificate = CodeSignatureBuilder.FindCertificate(Provision);

            byte[] Data = Certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, "A");
            File.WriteAllBytes(Path.Combine(Config.PCXcodeStagingDir, MacSigningIdentityFilename), Data);
            Config.CodeSigningIdentity  = Certificate.FriendlyName; // since the pipeline will use a temporary keychain that will contain only this certificate, this should be the only identity that will work
            CurrentBaseXCodeCommandLine = GetBaseXcodeCommandline();

            // get the UUID
            string AllText = File.ReadAllText(FinalMobileProvisionFilename);
            string UUID    = "";
            int    idx     = AllText.IndexOf("<key>UUID</key>");

            if (idx > 0)
            {
                idx = AllText.IndexOf("<string>", idx);
                if (idx > 0)
                {
                    idx += "<string>".Length;
                    UUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx);
                }
            }
            CurrentBaseXCodeCommandLine += String.Format(" PROVISIONING_PROFILE=" + UUID);

            // needs Mac line endings so it can be executed
            string SrcPath  = @"..\..\..\Build\" + Config.OSString + @"\XcodeSupportFiles\prepackage.sh";
            string DestPath = Path.Combine(Config.PCXcodeStagingDir, @"prepackage.sh");

            Program.Log(" ... '" + SrcPath + "' -> '" + DestPath + "'");
            string SHContents = File.ReadAllText(SrcPath);

            SHContents = SHContents.Replace("\r\n", "\n");
            File.WriteAllText(DestPath, SHContents);

            CookTime.CopySignedFiles();
        }
Пример #6
0
        /// <summary>
        /// Copy the files always needed (even in a stub IPA)
        /// </summary>
        static public void CopyFilesNeededForMakeApp()
        {
            // Copy Info.plist over (modifiying it as needed)
            string SourcePListFilename = Utilities.GetPrecompileSourcePListFilename();

            Utilities.PListHelper Info = Utilities.PListHelper.CreateFromFile(SourcePListFilename);

            // Edit the plist
            CookTime.UpdateVersion(Info);

            // Write out the <GameName>-Info.plist file to the xcode staging directory
            string TargetPListFilename = Path.Combine(Config.PCXcodeStagingDir, Program.GameName + "-Info.plist");

            Directory.CreateDirectory(Path.GetDirectoryName(TargetPListFilename));
            string OutString = Info.SaveToString();

            OutString = OutString.Replace("${EXECUTABLE_NAME}", Program.GameName);
            OutString = OutString.Replace("${BUNDLE_IDENTIFIER}", Program.GameName.Replace("_", ""));

            // 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}",
            };

            StringBuilder NewLaunchImagesString = new StringBuilder("<key>UILaunchImages~iphone</key>\n\t\t<array>\n");

            for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 3)
            {
                NewLaunchImagesString.Append("\t\t\t<dict>\n");
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageMinimumOSVersion</key>\n");
                NewLaunchImagesString.Append("\t\t\t\t<string>8.0</string>\n");
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageName</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 0]);
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageOrientation</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 1]);
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageSize</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 2]);
                NewLaunchImagesString.Append("\t\t\t</dict>\n");
            }

            // close it out
            NewLaunchImagesString.Append("\t\t\t</array>\n\t\t<key>UILaunchImages~ipad</key>");
            OutString = OutString.Replace("<key>UILaunchImages~ipad</key>", NewLaunchImagesString.ToString());

            byte[] RawInfoPList = Encoding.UTF8.GetBytes(OutString);
            File.WriteAllBytes(TargetPListFilename, RawInfoPList);

            Program.Log("Updating .plist: {0} --> {1}", SourcePListFilename, TargetPListFilename);

            // look for an entitlements file (optional)
            string SourceEntitlements = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".entitlements");

            // set where to make the entitlements file (
            string TargetEntitlements = Path.Combine(Config.PCXcodeStagingDir, Program.GameName + ".entitlements");

            if (File.Exists(SourceEntitlements))
            {
                FileOperations.CopyRequiredFile(SourceEntitlements, TargetEntitlements);
            }
            else
            {
                // we need to have something so Xcode will compile, so we just set the get-task-allow, since we know the value,
                // which is based on distribution or not (true means debuggable)
                File.WriteAllText(TargetEntitlements, string.Format("<plist><dict><key>get-task-allow</key><{0}/></dict></plist>",
                                                                    Config.bForDistribution ? "false" : "true"));
            }


            // Copy the no sign resource rules file over
            if (!Config.bForDistribution)
            {
                FileOperations.CopyRequiredFile(@"..\..\..\Build\IOS\XcodeSupportFiles\CustomResourceRules.plist", Path.Combine(Config.PCStagingRootDir, "CustomResourceRules.plist"));
            }

            // Copy the mobile provision file over
            string ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".mobileprovision");

            if (!File.Exists(ProvisionWithPrefix))
            {
                ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory + "/NotForLicensees/", Program.GameName + ".mobileprovision");
                if (!File.Exists(ProvisionWithPrefix))
                {
                    ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory, "UE4Game.mobileprovision");
                    if (!File.Exists(ProvisionWithPrefix))
                    {
                        ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory + "/NotForLicensees/", "UE4Game.mobileprovision");
                    }
                }
            }
            string FinalMobileProvisionFilename = Path.Combine(Config.PCXcodeStagingDir, MacMobileProvisionFilename);

            FileOperations.CopyRequiredFile(ProvisionWithPrefix, FinalMobileProvisionFilename);
            // make sure this .mobileprovision file is newer than any other .mobileprovision file on the Mac (this file gets multiple games named the same file,
            // so the time stamp checking can fail when moving between games, a la the buildmachines!)
            File.SetLastWriteTime(FinalMobileProvisionFilename, DateTime.UtcNow);

            FileOperations.CopyRequiredFile(Config.RootRelativePath + @"Engine\Intermediate\IOS\UE4.xcodeproj\project.pbxproj", Path.Combine(Config.PCXcodeStagingDir, @"project.pbxproj.datecheck"));

            // needs Mac line endings so it can be executed
            string SrcPath  = @"..\..\..\Build\IOS\XcodeSupportFiles\prepackage.sh";
            string DestPath = Path.Combine(Config.PCXcodeStagingDir, @"prepackage.sh");

            Program.Log(" ... '" + SrcPath + "' -> '" + DestPath + "'");
            string SHContents = File.ReadAllText(SrcPath);

            SHContents = SHContents.Replace("\r\n", "\n");
            File.WriteAllText(DestPath, SHContents);

            CookTime.CopySignedFiles();
        }