コード例 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="InDirectory"></param>
        /// <param name="InTargetPlatform"></param>
        /// <param name="OutRSAKeys"></param>
        /// <param name="OutAESKey"></param>
        public static void ParseEncryptionIni(DirectoryReference InDirectory, UnrealTargetPlatform InTargetPlatform, out String[] OutRSAKeys, out String OutAESKey)
        {
            OutAESKey  = String.Empty;
            OutRSAKeys = null;

            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InDirectory, InTargetPlatform);

            bool bSigningEnabled;

            Ini.GetBool("Core.Encryption", "SignPak", out bSigningEnabled);

            if (bSigningEnabled)
            {
                OutRSAKeys = new string[3];
                Ini.GetString("Core.Encryption", "rsa.privateexp", out OutRSAKeys[0]);
                Ini.GetString("Core.Encryption", "rsa.modulus", out OutRSAKeys[1]);
                Ini.GetString("Core.Encryption", "rsa.publicexp", out OutRSAKeys[2]);

                if (String.IsNullOrEmpty(OutRSAKeys[0]) || String.IsNullOrEmpty(OutRSAKeys[1]) || String.IsNullOrEmpty(OutRSAKeys[2]))
                {
                    OutRSAKeys = null;
                }
            }

            bool bEncryptionEnabled;

            Ini.GetBool("Core.Encryption", "EncryptPak", out bEncryptionEnabled);

            if (bEncryptionEnabled)
            {
                Ini.GetString("Core.Encryption", "aes.key", out OutAESKey);
            }
        }
コード例 #2
0
        private string GetRuntimeSetting(string Key)
        {
            ConfigHierarchy Ini = GetConfigCacheIni(ConfigHierarchyType.Engine);
            string          Value;

            Ini.GetString("/Script/LuminRuntimeSettings.LuminRuntimeSettings", Key, out Value);
            return(Value);
        }
コード例 #3
0
        protected static bool DoProjectSettingsMatchDefault(UnrealTargetPlatform Platform, DirectoryReference ProjectDirectoryName, string Section, string[] BoolKeys, string[] IntKeys, string[] StringKeys)
        {
            ConfigHierarchy ProjIni    = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, ProjectDirectoryName, Platform);
            ConfigHierarchy DefaultIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, (DirectoryReference)null, Platform);

            // look at all bool values
            if (BoolKeys != null)
            {
                foreach (string Key in BoolKeys)
                {
                    bool Default = false, Project = false;
                    DefaultIni.GetBool(Section, Key, out Default);
                    ProjIni.GetBool(Section, Key, out Project);
                    if (Default != Project)
                    {
                        Log.TraceInformationOnce(Key + " is not set to default. (" + Default + " vs. " + Project + ")");
                        return(false);
                    }
                }
            }

            // look at all int values
            if (IntKeys != null)
            {
                foreach (string Key in IntKeys)
                {
                    int Default = 0, Project = 0;
                    DefaultIni.GetInt32(Section, Key, out Default);
                    ProjIni.GetInt32(Section, Key, out Project);
                    if (Default != Project)
                    {
                        Log.TraceInformationOnce(Key + " is not set to default. (" + Default + " vs. " + Project + ")");
                        return(false);
                    }
                }
            }

            // look for all string values
            if (StringKeys != null)
            {
                foreach (string Key in StringKeys)
                {
                    string Default = "", Project = "";
                    DefaultIni.GetString(Section, Key, out Default);
                    ProjIni.GetString(Section, Key, out Project);
                    if (Default != Project)
                    {
                        Log.TraceInformationOnce(Key + " is not set to default. (" + Default + " vs. " + Project + ")");
                        return(false);
                    }
                }
            }

            // if we get here, we match all important settings
            return(true);
        }
コード例 #4
0
        protected string ReadIniString(string Key, string Section, string DefaultValue = null)
        {
            if (Key == null)
            {
                return(DefaultValue);
            }

            string Value;

            if (GameIni.GetString(Section, Key, out Value) && !string.IsNullOrWhiteSpace(Value))
            {
                return(Value);
            }

            if (EngineIni.GetString(Section, Key, out Value) && !string.IsNullOrWhiteSpace(Value))
            {
                return(Value);
            }

            return(DefaultValue);
        }
コード例 #5
0
        public override void GenerateGameProperties(UnrealTargetConfiguration Configuration, StringBuilder VCProjectFileContent, TargetType TargetType, DirectoryReference RootDirectory, FileReference TargetFilePath)
        {
            string          MinVersion       = string.Empty;
            string          MaxTestedVersion = string.Empty;
            ConfigHierarchy EngineIni        = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, RootDirectory, UnrealTargetPlatform.HoloLens);

            if (EngineIni != null)
            {
                EngineIni.GetString("/Script/HoloLensPlatformEditor.HoloLensTargetSettings", "MinimumPlatformVersion", out MinVersion);
                EngineIni.GetString("/Script/HoloLensPlatformEditor.HoloLensTargetSettings", "MaximumPlatformVersionTested", out MaxTestedVersion);
            }
            if (!string.IsNullOrEmpty(MinVersion))
            {
                VCProjectFileContent.Append("		<WindowsTargetPlatformMinVersion>"+ MinVersion + "</WindowsTargetPlatformMinVersion>" + ProjectFileGenerator.NewLine);
            }
            if (!string.IsNullOrEmpty(MaxTestedVersion))
            {
                VCProjectFileContent.Append("		<WindowsTargetPlatformVersion>"+ MaxTestedVersion + "</WindowsTargetPlatformVersion>" + ProjectFileGenerator.NewLine);
            }

            WindowsCompiler    Compiler = WindowsPlatform.GetDefaultCompiler(TargetFilePath);
            DirectoryReference PlatformWinMDLocation = HoloLens.GetCppCXMetadataLocation(Compiler, "Latest");

            if (PlatformWinMDLocation == null || !FileReference.Exists(FileReference.Combine(PlatformWinMDLocation, "platform.winmd")))
            {
                throw new BuildException("Unable to find platform.winmd for {0} toolchain; '{1}' is an invalid version", WindowsPlatform.GetCompilerName(Compiler), "Latest");
            }
            string FoundationWinMDPath = HoloLens.GetLatestMetadataPathForApiContract("Windows.Foundation.FoundationContract", Compiler);
            string UniversalWinMDPath  = HoloLens.GetLatestMetadataPathForApiContract("Windows.Foundation.UniversalApiContract", Compiler);

            VCProjectFileContent.Append("		<AdditionalOptions>/ZW /ZW:nostdlib</AdditionalOptions>"+ ProjectFileGenerator.NewLine);
            VCProjectFileContent.Append("		<NMakePreprocessorDefinitions>$(NMakePreprocessorDefinitions);PLATFORM_HOLOLENS=1;HOLOLENS=1;</NMakePreprocessorDefinitions>"+ ProjectFileGenerator.NewLine);
            if (PlatformWinMDLocation != null)
            {
                VCProjectFileContent.Append("		<NMakeAssemblySearchPath>$(NMakeAssemblySearchPath);"+ PlatformWinMDLocation + "</NMakeAssemblySearchPath>" + ProjectFileGenerator.NewLine);
            }
            VCProjectFileContent.Append("		<NMakeForcedUsingAssemblies>$(NMakeForcedUsingAssemblies);"+ FoundationWinMDPath + ";" + UniversalWinMDPath + ";platform.winmd</NMakeForcedUsingAssemblies>" + ProjectFileGenerator.NewLine);
        }
コード例 #6
0
        /// <summary>
        /// Find the default architecture for the given project
        /// </summary>
        public override string GetDefaultArchitecture(FileReference ProjectFile)
        {
            string ActiveArchitecture = DefaultArchitecture;

            // read settings from the config
            string EngineIniPath = ProjectFile != null ? ProjectFile.Directory.FullName : null;

            if (String.IsNullOrEmpty(EngineIniPath))
            {
                // If the project file hasn't been specified, try to get the path from -remoteini command line param
                EngineIniPath = UnrealBuildTool.GetRemoteIniPath();
            }
            DirectoryReference EngineIniDir = !String.IsNullOrEmpty(EngineIniPath) ? new DirectoryReference(EngineIniPath) : null;

            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, EngineIniDir, UnrealTargetPlatform.Linux);

            string LinuxArchitectureString;

            if (Ini.GetString("/Script/LinuxTargetPlatform.LinuxTargetSettings", "TargetArchitecture", out LinuxArchitectureString))
            {
                LinuxArchitecture Architecture;
                if (Enum.TryParse(LinuxArchitectureString, out Architecture))
                {
                    switch (Architecture)
                    {
                    default:
                        System.Console.WriteLine("Architecture enum value {0} does not map to a valid triplet.", Architecture);
                        break;

                    case LinuxArchitecture.X86_64UnknownLinuxGnu:
                        ActiveArchitecture = "x86_64-unknown-linux-gnu";
                        break;

                    case LinuxArchitecture.ArmUnknownLinuxGnueabihf:
                        ActiveArchitecture = "arm-unknown-linux-gnueabihf";
                        break;

                    case LinuxArchitecture.AArch64UnknownLinuxGnueabi:
                        ActiveArchitecture = "aarch64-unknown-linux-gnueabi";
                        break;

                    case LinuxArchitecture.I686UnknownLinuxGnu:
                        ActiveArchitecture = "i686-unknown-linux-gnu";
                        break;
                    }
                }
            }

            return(ActiveArchitecture);
        }
コード例 #7
0
        public static bool GeneratePList(string ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, string InEngineDir, string ExeName)
        {
            string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/Mac";
            string DestPListFile         = IntermediateDirectory + "/" + ExeName + "-Info.plist";
            string SrcPListFile          = (bIsUE4Game ? (InEngineDir + "Source/Programs/") : (ProjectDirectory + "/Source/")) + GameName + "/Resources/Mac/Info.plist";

            if (!File.Exists(SrcPListFile))
            {
                SrcPListFile = InEngineDir + "/Source/Runtime/Launch/Resources/Mac/Info.plist";
            }

            string PListData = null;

            if (File.Exists(SrcPListFile))
            {
                PListData = File.ReadAllText(SrcPListFile);
            }
            else
            {
                return(false);
            }

            // bundle identifier
            // plist replacements
            DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory);
            ConfigHierarchy    Ini    = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirRef, UnrealTargetPlatform.IOS);

            string BundleIdentifier;

            Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier);

            string BundleVersion = MacToolChain.LoadEngineDisplayVersion();

            PListData = PListData.Replace("${EXECUTABLE_NAME}", ExeName).Replace("${APP_NAME}", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", "")).Replace("${ICON_NAME}", GameName).Replace("${MACOSX_DEPLOYMENT_TARGET}", MacToolChain.Settings.MinMacOSVersion).Replace("${BUNDLE_VERSION}", BundleVersion);

            if (!Directory.Exists(IntermediateDirectory))
            {
                Directory.CreateDirectory(IntermediateDirectory);
            }
            File.WriteAllText(DestPListFile, PListData);

            return(true);
        }
コード例 #8
0
        public string GetMLSDKVersion(ConfigHierarchy EngineIni)
        {
            string MLSDKPath;
            string Major = "0";
            string Minor = "0";

            if (EngineIni.GetString("/Script/LuminPlatformEditor.MagicLeapSDKSettings", "MLSDKPath", out MLSDKPath) && !string.IsNullOrWhiteSpace(MLSDKPath))
            {
                Dictionary <string, string> PathEntry;
                ConfigHierarchy.TryParse(MLSDKPath, out PathEntry);
                MLSDKPath = PathEntry.Values.First();
            }
            if (string.IsNullOrWhiteSpace(MLSDKPath))
            {
                MLSDKPath = Environment.GetEnvironmentVariable("MLSDK");
            }
            if (!string.IsNullOrEmpty(MLSDKPath))
            {
                if (Directory.Exists(MLSDKPath))
                {
                    String VersionFile = string.Format("{0}/include/ml_version.h", MLSDKPath).Replace('/', Path.DirectorySeparatorChar);
                    if (File.Exists(VersionFile))
                    {
                        string          FileText     = File.ReadAllText(VersionFile);
                        string          Pattern      = @"(MLSDK_VERSION_MAJOR) (?'MAJOR'\d+).*(MLSDK_VERSION_MINOR) (?'MINOR'\d+).*(MLSDK_VERSION_REVISION) (?'REV'\d+)";
                        Regex           VersionRegex = new Regex(Pattern, RegexOptions.Singleline);
                        MatchCollection Matches      = VersionRegex.Matches(FileText);
                        if (Matches.Count > 0 &&
                            !string.IsNullOrEmpty(Matches[0].Groups["MAJOR"].Value) &&
                            !string.IsNullOrEmpty(Matches[0].Groups["MINOR"].Value))
                        {
                            Major = Matches[0].Groups["MAJOR"].Value;
                            Minor = Matches[0].Groups["MINOR"].Value;
                        }
                    }
                }
            }
            return(string.Format("{0}.{1}", Major, Minor));
        }
コード例 #9
0
        private bool SetupGraphicsDebugger(ReadOnlyTargetRules Target, CppCompileEnvironment CompileEnvironment, LinkEnvironment LinkEnvironment)
        {
            string          AndroidGraphicsDebugger;
            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(Target.ProjectFile), UnrealTargetPlatform.Android);

            Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "AndroidGraphicsDebugger", out AndroidGraphicsDebugger);

            if (AndroidGraphicsDebugger.ToLower() == "renderdoc")
            {
                string RenderDocPath;
                AndroidPlatformSDK.GetPath(Ini, "/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "RenderDocPath", out RenderDocPath);
                string RenderDocLibPath = Path.Combine(RenderDocPath, @"android\lib\armeabi-v7a");
                if (Directory.Exists(RenderDocLibPath))
                {
                    LinkEnvironment.LibraryPaths.Add(new DirectoryReference(RenderDocLibPath));
                    LinkEnvironment.AdditionalLibraries.Add("VkLayer_GLES_RenderDoc");
                    return(true);
                }
            }

            return(false);
        }
コード例 #10
0
        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
                ConfigHierarchy Ini        = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(ProjectFile), Platform);
                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";
                }

                NonShippingArchitectures = String.Join(",", GetNonShippingArchitectures(Ini));

                ShippingArchitectures = String.Join(",", GetShippingArchitectures(Ini));

                // 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;
        }
コード例 #11
0
        public string GenerateManifest(string ProjectName, bool bForDistribution, string Architecture)
        {
            ConfigHierarchy GameIni        = GetConfigCacheIni(ConfigHierarchyType.Game);
            string          ProjectVersion = string.Empty;

            GameIni.GetString("/Script/EngineSettings.GeneralProjectSettings", "ProjectVersion", out ProjectVersion);
            if (string.IsNullOrEmpty(ProjectVersion))
            {
                ProjectVersion = "1.0.0.0";
            }

            ConfigHierarchy EngineIni = GetConfigCacheIni(ConfigHierarchyType.Engine);
            Int32           VersionCode;

            EngineIni.GetInt32("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "VersionCode", out VersionCode);

            string SDKVersion             = GetMLSDKVersion(EngineIni);
            string PackageName            = GetPackageName(ProjectName);
            string ApplicationDisplayName = GetApplicationDisplayName(ProjectName);
            string MinimumAPILevel        = GetMinimumAPILevelRequired();
            string TargetExecutableName   = "bin/" + ProjectName;

            PackageManifest.version_name = ProjectVersion;
            PackageManifest.package      = PackageName;
            PackageManifest.version_code = Convert.ToUInt64(VersionCode);

            PackageManifest.application = new manifestApplication
            {
                sdk_version   = SDKVersion,
                min_api_level = MinimumAPILevel,
                visible_name  = ApplicationDisplayName
            };

            List <string> AppPrivileges;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "AppPrivileges", out AppPrivileges);

            List <string> ExtraComponentElements;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "ExtraComponentElements", out ExtraComponentElements);

            // We start with 1 since there will always be a 'root' <component>
            int Size = 1;

            Size += (AppPrivileges != null) ? AppPrivileges.Count : 0;
            Size += (ExtraComponentElements != null) ? ExtraComponentElements.Count : 0;
            // Increment Size here if more elements are required in the <application> node.

            // Index used for sibling elements (app privileges, root component and any extra components)
            int CurrentIndex = 0;

            PackageManifest.application.Items = new object[Size];
            // Remove all invalid strings from the list of strings
            AppPrivileges.RemoveAll(item => item == "Invalid");
            // Privileges get added first
            for (int Index = 0; Index < AppPrivileges.Count(); ++Index)
            {
                string TrimmedPrivilege = AppPrivileges[Index].Trim(' ');
                if (TrimmedPrivilege != "")
                {
                    PackageManifest.application.Items[CurrentIndex] = new manifestApplicationUsesprivilege
                    {
                        name = TrimmedPrivilege,
                    };
                    CurrentIndex++;
                }
            }

            // Then our root component, this is important as `mldb launch` will use the first component in the manifest
            PackageManifest.application.Items[CurrentIndex] = new manifestApplicationComponent();
            manifestApplicationComponent RootComponent = (manifestApplicationComponent)PackageManifest.application.Items[CurrentIndex];

            RootComponent.name         = ".fullscreen";
            RootComponent.visible_name = ApplicationDisplayName;
            RootComponent.binary_name  = TargetExecutableName;
            RootComponent.type         = GetApplicationType();

            // Sub-elements under root <component>
            List <string> ExtraComponentSubElements;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "ExtraComponentSubElements", out ExtraComponentSubElements);

            List <string> LocalizedAppNames;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "LocalizedAppNames", out LocalizedAppNames);

            // We start with 1 since there will always be an icon element
            int NumElementsInRootComponent = 1;

            NumElementsInRootComponent += (ExtraComponentSubElements != null) ? ExtraComponentSubElements.Count : 0;
            // If localized app names have been specified, add count of 1 for the <locale> tag.
            NumElementsInRootComponent += (LocalizedAppNames != null) ? 1 : 0;
            // Increment NumElementsInRootComponent here if more elements are required in the <component> node.

            RootComponent.Items = new object[NumElementsInRootComponent];

            // Root component icon
            Dictionary <string, manifestApplicationComponentIconTranslation> LocalizedIconsDict = new Dictionary <string, manifestApplicationComponentIconTranslation>();

            if (Directory.Exists(IconDirectory + "/Model"))
            {
                string[] IconModelSubDirectories = Directory.GetDirectories(IconDirectory + "/Model");
                foreach (var IconModelSubDirectory in IconModelSubDirectories)
                {
                    manifestApplicationComponentIconTranslation LocalizedIcon = new manifestApplicationComponentIconTranslation();
                    LocalizedIcon.language     = Path.GetFileName(IconModelSubDirectory);
                    LocalizedIcon.model_folder = GetIconModelStagingPath() + "/" + LocalizedIcon.language;
                    LocalizedIconsDict.Add(LocalizedIcon.language, LocalizedIcon);
                }
            }

            if (Directory.Exists(IconDirectory + "/Portal"))
            {
                string[] IconPortalSubDirectories = Directory.GetDirectories(IconDirectory + "/Portal");
                foreach (var IconPortalSubDirectory in IconPortalSubDirectories)
                {
                    manifestApplicationComponentIconTranslation LocalizedIcon;
                    string language = Path.GetFileName(IconPortalSubDirectory);
                    if (!LocalizedIconsDict.TryGetValue(language, out LocalizedIcon))
                    {
                        LocalizedIcon          = new manifestApplicationComponentIconTranslation();
                        LocalizedIcon.language = language;
                        LocalizedIconsDict.Add(LocalizedIcon.language, LocalizedIcon);
                    }

                    LocalizedIcon.portal_folder = GetIconPortalStagingPath() + "/" + LocalizedIcon.language;
                }
            }

            manifestApplicationComponentIconTranslation[] LocalizedIcons = new manifestApplicationComponentIconTranslation[LocalizedIconsDict.Count];
            int LocalizedIconIndex = 0;

            foreach (KeyValuePair <string, manifestApplicationComponentIconTranslation> LocalizedIconKVP in LocalizedIconsDict)
            {
                LocalizedIcons[LocalizedIconIndex++] = LocalizedIconKVP.Value;
            }

            RootComponent.Items[0] = new manifestApplicationComponentIcon();
            ((manifestApplicationComponentIcon)RootComponent.Items[0]).locale        = LocalizedIcons;
            ((manifestApplicationComponentIcon)RootComponent.Items[0]).model_folder  = GetIconModelStagingPath();
            ((manifestApplicationComponentIcon)RootComponent.Items[0]).portal_folder = GetIconPortalStagingPath();

            int RootComponentIndex = 1;

            if (ExtraComponentSubElements != null)
            {
                for (int Index = 0; Index < ExtraComponentSubElements.Count(); ++Index)
                {
                    Dictionary <string, string> NodeContent;
                    if (ConfigHierarchy.TryParse(ExtraComponentSubElements[Index], out NodeContent))
                    {
                        RootComponent.Items[RootComponentIndex] = GetComponentSubElement(NodeContent["ElementType"], NodeContent["Value"]);
                        RootComponentIndex++;
                    }
                }
            }

            // Localized app names
            if (LocalizedAppNames != null && LocalizedAppNames.Count > 0)
            {
                manifestApplicationComponentLocale LocaleTag = new manifestApplicationComponentLocale();
                LocaleTag.Items = new manifestApplicationComponentLocaleTranslation[LocalizedAppNames.Count];
                RootComponent.Items[RootComponentIndex] = LocaleTag;
                RootComponentIndex++;

                for (int i = 0; i < LocalizedAppNames.Count; ++i)
                {
                    Dictionary <string, string> NodeContent;
                    if (ConfigHierarchy.TryParse(LocalizedAppNames[i], out NodeContent))
                    {
                        LocaleTag.Items[i] = new manifestApplicationComponentLocaleTranslation
                        {
                            language     = NodeContent["LanguageCode"],
                            visible_name = NodeContent["AppName"]
                        };
                    }
                }
            }

            // Finally, add additional components
            CurrentIndex++;
            if (ExtraComponentElements != null)
            {
                for (int Index = 0; Index < ExtraComponentElements.Count(); ++Index)
                {
                    Dictionary <string, string> ComponentElement;
                    if (ConfigHierarchy.TryParse(ExtraComponentElements[Index], out ComponentElement))
                    {
                        PackageManifest.application.Items[CurrentIndex] = GetComponentElement(ComponentElement);
                        CurrentIndex++;
                    }
                }
            }

            // Wrap up serialization
            XmlSerializer           PackageManifestSerializer = new XmlSerializer(PackageManifest.GetType());
            XmlSerializerNamespaces MLNamespace = new XmlSerializerNamespaces();

            MLNamespace.Add("ml", "magicleap");
            StringWriter Writer = new StringWriter();

            PackageManifestSerializer.Serialize(Writer, PackageManifest, MLNamespace);

            // allow plugins to modify final manifest HERE
            XDocument XDoc;

            try
            {
                XDoc = XDocument.Parse(Writer.ToString());
            }
            catch (Exception e)
            {
                throw new BuildException("LuminManifest.xml is invalid {0}\n{1}", e, Writer.ToString());
            }

            UPL.ProcessPluginNode(Architecture, "luminManifestUpdates", "", ref XDoc);
            return(XDoc.ToString());
        }
コード例 #12
0
ファイル: RemoteMac.cs プロジェクト: IvanYangYangXi/UE4-GW
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="ProjectFile">Project to read settings from</param>
        public RemoteMac(FileReference ProjectFile)
        {
            this.RsyncExe         = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "ThirdPartyNotUE", "DeltaCopy", "Binaries", "Rsync.exe");
            this.SshExe           = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "ThirdPartyNotUE", "DeltaCopy", "Binaries", "Ssh.exe");
            this.ProjectFile      = ProjectFile;
            this.ProjectDirectory = DirectoryReference.FromFile(ProjectFile);

            // Apply settings from the XML file
            XmlConfig.ApplyTo(this);

            // Get the project config file path
            DirectoryReference EngineIniPath = ProjectFile != null ? ProjectFile.Directory : null;

            if (EngineIniPath == null && UnrealBuildTool.GetRemoteIniPath() != null)
            {
                EngineIniPath = new DirectoryReference(UnrealBuildTool.GetRemoteIniPath());
            }
            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, EngineIniPath, UnrealTargetPlatform.IOS);

            // Read the project settings if we don't have anything in the build configuration settings
            if (String.IsNullOrEmpty(ServerName))
            {
                // Read the server name
                string IniServerName;
                if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RemoteServerName", out IniServerName) && !String.IsNullOrEmpty(IniServerName))
                {
                    this.ServerName = IniServerName;
                }
                else
                {
                    throw new BuildException("Remote compiling requires a server name. Use the editor (Project Settings > IOS) to set up your remote compilation settings.");
                }

                // Parse the username
                string IniUserName;
                if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RSyncUsername", out IniUserName) && !String.IsNullOrEmpty(IniUserName))
                {
                    this.UserName = IniUserName;
                }
            }

            // Split port out from the server name
            int PortIdx = ServerName.LastIndexOf(':');

            if (PortIdx != -1)
            {
                string Port = ServerName.Substring(PortIdx + 1);
                if (!int.TryParse(Port, out ServerPort))
                {
                    throw new BuildException("Unable to parse port number from '{0}'", ServerName);
                }
                ServerName = ServerName.Substring(0, PortIdx);
            }

            // If a user name is not set, use the current user
            if (String.IsNullOrEmpty(UserName))
            {
                UserName = Environment.UserName;
            }

            // Print out the server info
            Log.TraceInformation("[Remote] Using remote server '{0}' on port {1} (user '{2}')", ServerName, ServerPort, UserName);

            // Get the path to the SSH private key
            string OverrideSshPrivateKeyPath;

            if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SSHPrivateKeyOverridePath", out OverrideSshPrivateKeyPath) && !String.IsNullOrEmpty(OverrideSshPrivateKeyPath))
            {
                SshPrivateKey = new FileReference(OverrideSshPrivateKeyPath);
                if (!FileReference.Exists(SshPrivateKey))
                {
                    throw new BuildException("SSH private key specified in config file ({0}) does not exist.", SshPrivateKey);
                }
            }

            // If it's not set, look in the standard locations. If that fails, spawn the batch file to generate one.
            if (SshPrivateKey == null && !TryGetSshPrivateKey(out SshPrivateKey))
            {
                Log.TraceWarning("No SSH private key found for {0}@{1}. Launching SSH to generate one.", UserName, ServerName);

                StringBuilder CommandLine = new StringBuilder();
                CommandLine.AppendFormat("/C \"\"{0}\"", FileReference.Combine(UnrealBuildTool.EngineDirectory, "Build", "BatchFiles", "MakeAndInstallSSHKey.bat"));
                CommandLine.AppendFormat(" \"{0}\"", SshExe);
                CommandLine.AppendFormat(" \"{0}\"", ServerPort);
                CommandLine.AppendFormat(" \"{0}\"", RsyncExe);
                CommandLine.AppendFormat(" \"{0}\"", UserName);
                CommandLine.AppendFormat(" \"{0}\"", ServerName);
                CommandLine.AppendFormat(" \"{0}\"", DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.MyDocuments));
                CommandLine.AppendFormat(" \"{0}\"", GetLocalCygwinPath(DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.MyDocuments)));
                CommandLine.AppendFormat(" \"{0}\"", UnrealBuildTool.EngineDirectory);
                CommandLine.Append("\"");

                using (Process ChildProcess = Process.Start("C:\\Windows\\System32\\Cmd.exe", CommandLine.ToString()))
                {
                    ChildProcess.WaitForExit();
                }

                if (!TryGetSshPrivateKey(out SshPrivateKey))
                {
                    throw new BuildException("Failed to generate SSH private key for {0}@{1}.", UserName, ServerName);
                }
            }

            // resolve the rest of the strings
            RsyncAuthentication = ExpandVariables(RsyncAuthentication);
            SshAuthentication   = ExpandVariables(SshAuthentication);

            // Get the remote base directory
            RemoteBaseDir = String.Format("/Users/{0}/UE4/Builds/{1}", UserName, Environment.MachineName);

            // Build the list of directory mappings between the local and remote machines
            Mappings = new List <RemoteMapping>();
            Mappings.Add(new RemoteMapping(UnrealBuildTool.EngineDirectory, GetRemotePath(UnrealBuildTool.EngineDirectory)));
            if (ProjectFile != null && !ProjectFile.IsUnderDirectory(UnrealBuildTool.EngineDirectory))
            {
                Mappings.Add(new RemoteMapping(ProjectFile.Directory, GetRemotePath(ProjectFile.Directory)));
            }

            // Build a list of arguments for SSH
            CommonSshArguments = new List <string>();
            CommonSshArguments.Add("-o BatchMode=yes");
            CommonSshArguments.Add(SshAuthentication);
            CommonSshArguments.Add(String.Format("-p {0}", ServerPort));
            CommonSshArguments.Add(String.Format("\"{0}@{1}\"", UserName, ServerName));

            // Build a list of arguments for Rsync
            CommonRsyncArguments = new List <string>();
            CommonRsyncArguments.Add("--compress");
            CommonRsyncArguments.Add("--recursive");
            CommonRsyncArguments.Add("--delete");            // Delete anything not in the source directory
            CommonRsyncArguments.Add("--delete-excluded");   // Delete anything not in the source directory
            CommonRsyncArguments.Add("--times");             // Preserve modification times
            CommonRsyncArguments.Add("--verbose");
            CommonRsyncArguments.Add("-m");
            CommonRsyncArguments.Add("--chmod=ug=rwX,o=rxX");
            CommonRsyncArguments.Add(String.Format("--rsh=\"{0} -p {1}\"", RsyncAuthentication, ServerPort));
        }
コード例 #13
0
        /// <summary>
        /// Parse crypto settings from INI file
        /// </summary>
        public static CryptoSettings ParseCryptoSettings(DirectoryReference InProjectDirectory, UnrealTargetPlatform InTargetPlatform)
        {
            CryptoSettings Settings = new CryptoSettings();

            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, InProjectDirectory, InTargetPlatform);

            Ini.GetBool("PlatformCrypto", "PlatformRequiresDataCrypto", out Settings.bDataCryptoRequired);
            Ini.GetBool("PlatformCrypto", "PakSigningRequired", out Settings.PakSigningRequired);
            Ini.GetBool("PlatformCrypto", "PakEncryptionRequired", out Settings.PakEncryptionRequired);

            {
                // Start by parsing the legacy encryption.ini settings
                Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InProjectDirectory, InTargetPlatform);
                Ini.GetBool("Core.Encryption", "SignPak", out Settings.bEnablePakSigning);

                string[] SigningKeyStrings = new string[3];
                Ini.GetString("Core.Encryption", "rsa.privateexp", out SigningKeyStrings[0]);
                Ini.GetString("Core.Encryption", "rsa.modulus", out SigningKeyStrings[1]);
                Ini.GetString("Core.Encryption", "rsa.publicexp", out SigningKeyStrings[2]);

                if (String.IsNullOrEmpty(SigningKeyStrings[0]) || String.IsNullOrEmpty(SigningKeyStrings[1]) || String.IsNullOrEmpty(SigningKeyStrings[2]))
                {
                    SigningKeyStrings = null;
                }
                else
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PrivateKey.Exponent = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[0]), 64);
                    Settings.SigningKey.PrivateKey.Modulus  = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[1]), 64);
                    Settings.SigningKey.PublicKey.Exponent  = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[2]), 64);
                    Settings.SigningKey.PublicKey.Modulus   = Settings.SigningKey.PrivateKey.Modulus;

                    if ((Settings.SigningKey.PrivateKey.Exponent.Length > 64) ||
                        (Settings.SigningKey.PrivateKey.Modulus.Length > 64) ||
                        (Settings.SigningKey.PublicKey.Exponent.Length > 64) ||
                        (Settings.SigningKey.PublicKey.Modulus.Length > 64))
                    {
                        throw new Exception(string.Format("[{0}] Signing keys parsed from encryption.ini are too long. They must be a maximum of 64 bytes long!", InProjectDirectory));
                    }
                }

                Ini.GetBool("Core.Encryption", "EncryptPak", out Settings.bEnablePakIndexEncryption);
                Settings.bEnablePakFullAssetEncryption = false;
                Settings.bEnablePakUAssetEncryption    = false;
                Settings.bEnablePakIniEncryption       = Settings.bEnablePakIndexEncryption;

                string EncryptionKeyString;
                Ini.GetString("Core.Encryption", "aes.key", out EncryptionKeyString);
                Settings.EncryptionKey = new EncryptionKey();

                if (EncryptionKeyString.Length > 0)
                {
                    if (EncryptionKeyString.Length < 32)
                    {
                        Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too short. It must be 32 bytes, so will be padded with 0s, giving sub-optimal security!");
                    }
                    else if (EncryptionKeyString.Length > 32)
                    {
                        Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too long. It must be 32 bytes, so will be truncated!");
                    }

                    Settings.EncryptionKey.Key = ParseAnsiStringToByteArray(EncryptionKeyString, 32);
                }
            }

            Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Crypto, InProjectDirectory, InTargetPlatform);
            string SectionName = "/Script/CryptoKeys.CryptoKeysSettings";
            ConfigHierarchySection CryptoSection = Ini.FindSection(SectionName);

            // If we have new format crypto keys, read them in over the top of the legacy settings
            if (CryptoSection != null && CryptoSection.KeyNames.Count() > 0)
            {
                Ini.GetBool(SectionName, "bEnablePakSigning", out Settings.bEnablePakSigning);
                Ini.GetBool(SectionName, "bEncryptPakIniFiles", out Settings.bEnablePakIniEncryption);
                Ini.GetBool(SectionName, "bEncryptPakIndex", out Settings.bEnablePakIndexEncryption);
                Ini.GetBool(SectionName, "bEncryptUAssetFiles", out Settings.bEnablePakUAssetEncryption);
                Ini.GetBool(SectionName, "bEncryptAllAssetFiles", out Settings.bEnablePakFullAssetEncryption);

                // Parse encryption key
                string EncryptionKeyString;
                Ini.GetString(SectionName, "EncryptionKey", out EncryptionKeyString);
                if (!string.IsNullOrEmpty(EncryptionKeyString))
                {
                    Settings.EncryptionKey      = new EncryptionKey();
                    Settings.EncryptionKey.Key  = System.Convert.FromBase64String(EncryptionKeyString);
                    Settings.EncryptionKey.Guid = Guid.Empty.ToString();
                    Settings.EncryptionKey.Name = "Embedded";
                }

                // Parse secondary encryption keys
                List <EncryptionKey> SecondaryEncryptionKeys = new List <EncryptionKey>();
                List <string>        SecondaryEncryptionKeyStrings;

                if (Ini.GetArray(SectionName, "SecondaryEncryptionKeys", out SecondaryEncryptionKeyStrings))
                {
                    foreach (string KeySource in SecondaryEncryptionKeyStrings)
                    {
                        EncryptionKey NewKey = new EncryptionKey();
                        SecondaryEncryptionKeys.Add(NewKey);

                        Regex Search = new Regex("\\(Guid=(?\'Guid\'.*),Name=\\\"(?\'Name\'.*)\\\",Key=\\\"(?\'Key\'.*)\\\"\\)");
                        Match Match  = Search.Match(KeySource);
                        if (Match.Success)
                        {
                            foreach (string GroupName in Search.GetGroupNames())
                            {
                                string Value = Match.Groups[GroupName].Value;
                                if (GroupName == "Guid")
                                {
                                    NewKey.Guid = Value;
                                }
                                else if (GroupName == "Name")
                                {
                                    NewKey.Name = Value;
                                }
                                else if (GroupName == "Key")
                                {
                                    NewKey.Key = System.Convert.FromBase64String(Value);
                                }
                            }
                        }
                    }
                }

                Settings.SecondaryEncryptionKeys = SecondaryEncryptionKeys.ToArray();

                // Parse signing key
                string PrivateExponent, PublicExponent, Modulus;
                Ini.GetString(SectionName, "SigningPrivateExponent", out PrivateExponent);
                Ini.GetString(SectionName, "SigningModulus", out Modulus);
                Ini.GetString(SectionName, "SigningPublicExponent", out PublicExponent);

                if (!String.IsNullOrEmpty(PrivateExponent) && !String.IsNullOrEmpty(PublicExponent) && !String.IsNullOrEmpty(Modulus))
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PublicKey.Exponent  = System.Convert.FromBase64String(PublicExponent);
                    Settings.SigningKey.PublicKey.Modulus   = System.Convert.FromBase64String(Modulus);
                    Settings.SigningKey.PrivateKey.Exponent = System.Convert.FromBase64String(PrivateExponent);
                    Settings.SigningKey.PrivateKey.Modulus  = Settings.SigningKey.PublicKey.Modulus;
                }
            }

            // Parse project dynamic keychain keys
            if (InProjectDirectory != null)
            {
                ConfigHierarchy GameIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Game, InProjectDirectory, InTargetPlatform);
                if (GameIni != null)
                {
                    string Filename;
                    if (GameIni.GetString("ContentEncryption", "ProjectKeyChain", out Filename))
                    {
                        FileReference ProjectKeyChainFile = FileReference.Combine(InProjectDirectory, "Content", Filename);
                        if (FileReference.Exists(ProjectKeyChainFile))
                        {
                            List <EncryptionKey> EncryptionKeys = new List <EncryptionKey>();

                            if (Settings.SecondaryEncryptionKeys != null)
                            {
                                EncryptionKeys.AddRange(Settings.SecondaryEncryptionKeys);
                            }

                            string[] Lines = FileReference.ReadAllLines(ProjectKeyChainFile);
                            foreach (string Line in Lines)
                            {
                                string[] KeyParts = Line.Split(':');
                                if (KeyParts.Length == 4)
                                {
                                    EncryptionKey NewKey = new EncryptionKey();

                                    NewKey.Name = KeyParts[0];
                                    NewKey.Guid = KeyParts[2];
                                    NewKey.Key  = System.Convert.FromBase64String(KeyParts[3]);

                                    EncryptionKey ExistingKey = EncryptionKeys.Find((EncryptionKey OtherKey) => { return(OtherKey.Guid == NewKey.Guid); });
                                    if (ExistingKey != null && !CompareKey(ExistingKey.Key, NewKey.Key))
                                    {
                                        throw new Exception("Found multiple encryption keys with the same guid but different AES keys while merging secondary keys from the project key-chain!");
                                    }

                                    EncryptionKeys.Add(NewKey);
                                }
                            }

                            Settings.SecondaryEncryptionKeys = EncryptionKeys.ToArray();
                        }
                    }
                }
            }

            if (!Settings.bDataCryptoRequired)
            {
                CryptoSettings NewSettings = new CryptoSettings();
                NewSettings.SecondaryEncryptionKeys = Settings.SecondaryEncryptionKeys;
                Settings = NewSettings;
            }
            else
            {
                if (!Settings.PakSigningRequired)
                {
                    Settings.bEnablePakSigning = false;
                    Settings.SigningKey        = null;
                }

                if (!Settings.PakEncryptionRequired)
                {
                    Settings.bEnablePakFullAssetEncryption = false;
                    Settings.bEnablePakIndexEncryption     = false;
                    Settings.bEnablePakIniEncryption       = false;
                    Settings.EncryptionKey = null;
                    Settings.SigningKey    = null;
                }
            }

            // Check if we have a valid signing key that is of the old short form
            if (Settings.SigningKey != null && Settings.SigningKey.IsValid() && Settings.SigningKey.IsUnsecureLegacyKey())
            {
                Log.TraceWarningOnce("Project signing keys found in '{0}' are of the old insecure short format. Please regenerate them using the project crypto settings panel in the editor!", InProjectDirectory);
            }

            // Validate the settings we have read
            if (Settings.bDataCryptoRequired && Settings.bEnablePakSigning && (Settings.SigningKey == null || !Settings.SigningKey.IsValid()))
            {
                Log.TraceWarningOnce("Pak signing is enabled, but no valid signing keys were found. Please generate a key in the editor project crypto settings. Signing will be disabled");
                Settings.bEnablePakSigning = false;
            }

            if (Settings.bDataCryptoRequired && Settings.IsAnyEncryptionEnabled() && (Settings.EncryptionKey == null || !Settings.EncryptionKey.IsValid()))
            {
                Log.TraceWarningOnce("Pak encryption is enabled, but no valid encryption key was found. Please generate a key in the editor project crypto settings. Encryption will be disabled");
                Settings.bEnablePakUAssetEncryption    = false;
                Settings.bEnablePakFullAssetEncryption = false;
                Settings.bEnablePakIndexEncryption     = false;
                Settings.bEnablePakIniEncryption       = false;
            }

            return(Settings);
        }
コード例 #14
0
        public string GenerateManifest(string ProjectName, bool bForDistribution, string Architecture)
        {
            ConfigHierarchy GameIni        = GetConfigCacheIni(ConfigHierarchyType.Game);
            string          ProjectVersion = string.Empty;

            GameIni.GetString("/Script/EngineSettings.GeneralProjectSettings", "ProjectVersion", out ProjectVersion);
            if (string.IsNullOrEmpty(ProjectVersion))
            {
                ProjectVersion = "1.0.0.0";
            }

            ConfigHierarchy EngineIni = GetConfigCacheIni(ConfigHierarchyType.Engine);
            int             VersionCode;

            EngineIni.GetInt32("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "VersionCode", out VersionCode);

            bool bInternetRequired;

            EngineIni.GetBool("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "bInternetRequired", out bInternetRequired);

            StringBuilder Text = new StringBuilder();

            string PackageName            = GetPackageName(ProjectName);
            string ApplicationDisplayName = GetApplicationDisplayName(ProjectName);
            string TargetExecutableName   = "bin/" + ProjectName;

            Text.AppendLine(string.Format("<manifest xmlns:ml=\"magicleap\" ml:package=\"{0}\" ml:version_name=\"{1}\" ml:version_code=\"{2}\">", PackageName, ProjectVersion, VersionCode));
            // @mltodo: query sdk_version
            Text.AppendLine(string.Format("\t<application ml:visible_name=\"{0}\" ml:is_debuggable=\"{1}\" ml:sdk_version=\"1.0\" ml:minimum_os=\"mlos_1.0\" ml:internet_required=\"{2}\">", ApplicationDisplayName, bForDistribution ? "false" : "true", bInternetRequired ? "true" : "false"));
            Text.AppendLine(string.Format("\t\t<component ml:name=\".fullscreen\" ml:visible_name=\"{0}\" ml:binary_name=\"{1}\" ml:type=\"{2}\">", ApplicationDisplayName, TargetExecutableName, GetApplicationType()));

            List <string> AppPrivileges;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "AppPrivileges", out AppPrivileges);
            if (AppPrivileges != null)
            {
                foreach (string Privilege in AppPrivileges)
                {
                    string TrimmedPrivilege = Privilege.Trim(' ');
                    if (TrimmedPrivilege != "")
                    {
                        string PrivilegeString = string.Format("\t\t\t<uses-privilege ml:name=\"{0}\"/>", TrimmedPrivilege);
                        if (!Text.ToString().Contains(PrivilegeString))
                        {
                            Text.AppendLine(PrivilegeString);
                        }
                    }
                }
            }

            string IconTag = string.Format("<icon ml:name=\"fullscreen\" ml:model_folder=\"{0}\" ml:portal_folder=\"{1}\"/>", GetIconModelStagingPath(), GetIconPortalStagingPath());

            Text.AppendLine(string.Format("\t\t\t{0}", IconTag));

            List <string> ExtraComponentNodes;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "ExtraComponentNodes", out ExtraComponentNodes);
            if (ExtraComponentNodes != null)
            {
                foreach (string ComponentNode in ExtraComponentNodes)
                {
                    Text.AppendLine(string.Format("\t\t\t{0}", ComponentNode));
                }
            }

            Text.AppendLine("\t\t</component>");

            List <string> ExtraApplicationNodes;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "ExtraApplicationNodes", out ExtraApplicationNodes);
            if (ExtraApplicationNodes != null)
            {
                foreach (string ApplicationNode in ExtraApplicationNodes)
                {
                    Text.AppendLine(string.Format("\t\t{0}", ApplicationNode));
                }
            }

            Text.AppendLine(string.Format("\t\t{0}", IconTag));
            Text.AppendLine("\t</application>");
            Text.AppendLine("</manifest>");

            // allow plugins to modify final manifest HERE
            XDocument XDoc;

            try
            {
                XDoc = XDocument.Parse(Text.ToString());
            }
            catch (Exception e)
            {
                throw new BuildException("LuminManifest.xml is invalid {0}\n{1}", e, Text.ToString());
            }

            UPL.ProcessPluginNode(Architecture, "luminManifestUpdates", "", ref XDoc);
            return(XDoc.ToString());
        }
コード例 #15
0
ファイル: Crypto.cs プロジェクト: ragnarula/ActionRPGEngine
        /// <summary>
        /// Parse crypto settings from INI file
        /// </summary>
        public static CryptoSettings ParseCryptoSettings(DirectoryReference InProjectDirectory, UnrealTargetPlatform InTargetPlatform)
        {
            CryptoSettings Settings = new CryptoSettings();

            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, InProjectDirectory, InTargetPlatform);

            Ini.GetBool("PlatformCrypto", "PlatformRequiresDataCrypto", out Settings.bDataCryptoRequired);

            // For now, we'll just not parse any keys if data crypto is disabled for this platform. In the future, we might want to use
            // these keys for non-data purposes (other general purpose encryption maybe?)
            if (!Settings.bDataCryptoRequired)
            {
                return(Settings);
            }

            {
                // Start by parsing the legacy encryption.ini settings
                Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InProjectDirectory, InTargetPlatform);
                Ini.GetBool("Core.Encryption", "SignPak", out Settings.bEnablePakSigning);

                string[] SigningKeyStrings = new string[3];
                Ini.GetString("Core.Encryption", "rsa.privateexp", out SigningKeyStrings[0]);
                Ini.GetString("Core.Encryption", "rsa.modulus", out SigningKeyStrings[1]);
                Ini.GetString("Core.Encryption", "rsa.publicexp", out SigningKeyStrings[2]);

                if (String.IsNullOrEmpty(SigningKeyStrings[0]) || String.IsNullOrEmpty(SigningKeyStrings[1]) || String.IsNullOrEmpty(SigningKeyStrings[2]))
                {
                    SigningKeyStrings = null;
                }
                else
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PrivateKey.Exponent = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[0]), 64);
                    Settings.SigningKey.PrivateKey.Modulus  = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[1]), 64);
                    Settings.SigningKey.PublicKey.Exponent  = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[2]), 64);
                    Settings.SigningKey.PublicKey.Modulus   = Settings.SigningKey.PrivateKey.Modulus;

                    if ((Settings.SigningKey.PrivateKey.Exponent.Length > 64) ||
                        (Settings.SigningKey.PrivateKey.Modulus.Length > 64) ||
                        (Settings.SigningKey.PublicKey.Exponent.Length > 64) ||
                        (Settings.SigningKey.PublicKey.Modulus.Length > 64))
                    {
                        throw new Exception(string.Format("[{0}] Signing keys parsed from encryption.ini are too long. They must be a maximum of 64 bytes long!", InProjectDirectory));
                    }
                }

                Ini.GetBool("Core.Encryption", "EncryptPak", out Settings.bEnablePakIndexEncryption);
                Settings.bEnablePakFullAssetEncryption = false;
                Settings.bEnablePakUAssetEncryption    = false;
                Settings.bEnablePakIniEncryption       = Settings.bEnablePakIndexEncryption;

                string EncryptionKeyString;
                Ini.GetString("Core.Encryption", "aes.key", out EncryptionKeyString);
                Settings.EncryptionKey = new EncryptionKey();

                if (EncryptionKeyString.Length > 0)
                {
                    if (EncryptionKeyString.Length < 32)
                    {
                        Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too short. It must be 32 bytes, so will be padded with 0s, giving sub-optimal security!");
                    }
                    else if (EncryptionKeyString.Length > 32)
                    {
                        Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too long. It must be 32 bytes, so will be truncated!");
                    }

                    Settings.EncryptionKey.Key = ParseAnsiStringToByteArray(EncryptionKeyString, 32);
                }
            }

            Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Crypto, InProjectDirectory, InTargetPlatform);
            string SectionName = "/Script/CryptoKeys.CryptoKeysSettings";
            ConfigHierarchySection CryptoSection = Ini.FindSection(SectionName);

            // If we have new format crypto keys, read them in over the top of the legacy settings
            if (CryptoSection != null && CryptoSection.KeyNames.Count() > 0)
            {
                Ini.GetBool(SectionName, "bEnablePakSigning", out Settings.bEnablePakSigning);
                Ini.GetBool(SectionName, "bEncryptPakIniFiles", out Settings.bEnablePakIniEncryption);
                Ini.GetBool(SectionName, "bEncryptPakIndex", out Settings.bEnablePakIndexEncryption);
                Ini.GetBool(SectionName, "bEncryptUAssetFiles", out Settings.bEnablePakUAssetEncryption);
                Ini.GetBool(SectionName, "bEncryptAllAssetFiles", out Settings.bEnablePakFullAssetEncryption);

                // Parse encryption key
                string EncryptionKeyString;
                Ini.GetString(SectionName, "EncryptionKey", out EncryptionKeyString);
                if (!string.IsNullOrEmpty(EncryptionKeyString))
                {
                    Settings.EncryptionKey     = new EncryptionKey();
                    Settings.EncryptionKey.Key = System.Convert.FromBase64String(EncryptionKeyString);
                }

                // Parse signing key
                string PrivateExponent, PublicExponent, Modulus;
                Ini.GetString(SectionName, "SigningPrivateExponent", out PrivateExponent);
                Ini.GetString(SectionName, "SigningModulus", out Modulus);
                Ini.GetString(SectionName, "SigningPublicExponent", out PublicExponent);

                if (!String.IsNullOrEmpty(PrivateExponent) && !String.IsNullOrEmpty(PublicExponent) && !String.IsNullOrEmpty(Modulus))
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PublicKey.Exponent  = System.Convert.FromBase64String(PublicExponent);
                    Settings.SigningKey.PublicKey.Modulus   = System.Convert.FromBase64String(Modulus);
                    Settings.SigningKey.PrivateKey.Exponent = System.Convert.FromBase64String(PrivateExponent);
                    Settings.SigningKey.PrivateKey.Modulus  = Settings.SigningKey.PublicKey.Modulus;
                }
            }

            return(Settings);
        }
コード例 #16
0
        public string GenerateManifest(string ProjectName, bool bForDistribution, string Architecture)
        {
            ConfigHierarchy GameIni        = GetConfigCacheIni(ConfigHierarchyType.Game);
            string          ProjectVersion = string.Empty;

            GameIni.GetString("/Script/EngineSettings.GeneralProjectSettings", "ProjectVersion", out ProjectVersion);
            if (string.IsNullOrEmpty(ProjectVersion))
            {
                ProjectVersion = "1.0.0.0";
            }

            ConfigHierarchy EngineIni = GetConfigCacheIni(ConfigHierarchyType.Engine);
            int             VersionCode;

            EngineIni.GetInt32("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "VersionCode", out VersionCode);

            string SDKVersion = GetMLSDKVersion(EngineIni);

            StringBuilder Text = new StringBuilder();

            string PackageName            = GetPackageName(ProjectName);
            string ApplicationDisplayName = GetApplicationDisplayName(ProjectName);
            string MinimumAPILevel        = GetMinimumAPILevelRequired();
            string TargetExecutableName   = "bin/" + ProjectName;

            Text.AppendLine(string.Format("<manifest xmlns:ml=\"magicleap\" ml:package=\"{0}\" ml:version_name=\"{1}\" ml:version_code=\"{2}\">", PackageName, ProjectVersion, VersionCode));
            Text.AppendLine(string.Format("\t<application ml:visible_name=\"{0}\" ml:sdk_version=\"{1}\" ml:min_api_level=\"{2}\">",
                                          ApplicationDisplayName,
                                          SDKVersion,
                                          MinimumAPILevel));
            GetAppPrivileges(EngineIni, Text);
            Text.AppendLine(string.Format("\t\t<component ml:name=\".fullscreen\" ml:visible_name=\"{0}\" ml:binary_name=\"{1}\" ml:type=\"{2}\">", ApplicationDisplayName, TargetExecutableName, GetApplicationType()));

            string IconTag = string.Format("<icon ml:model_folder=\"{0}\" ml:portal_folder=\"{1}\"/>", GetIconModelStagingPath(), GetIconPortalStagingPath());

            Text.AppendLine(string.Format("\t\t\t{0}", IconTag));

            List <string> ExtraComponentNodes;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "ExtraComponentNodes", out ExtraComponentNodes);
            if (ExtraComponentNodes != null)
            {
                foreach (string ComponentNode in ExtraComponentNodes)
                {
                    Text.AppendLine(string.Format("\t\t\t{0}", ComponentNode));
                }
            }

            Text.AppendLine("\t\t</component>");

            List <string> ExtraApplicationNodes;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "ExtraApplicationNodes", out ExtraApplicationNodes);
            if (ExtraApplicationNodes != null)
            {
                foreach (string ApplicationNode in ExtraApplicationNodes)
                {
                    Text.AppendLine(string.Format("\t\t{0}", ApplicationNode));
                }
            }

            Text.AppendLine("\t</application>");
            Text.AppendLine("</manifest>");

            // allow plugins to modify final manifest HERE
            XDocument XDoc;

            try
            {
                XDoc = XDocument.Parse(Text.ToString());
            }
            catch (Exception e)
            {
                throw new BuildException("LuminManifest.xml is invalid {0}\n{1}", e, Text.ToString());
            }

            UPL.ProcessPluginNode(Architecture, "luminManifestUpdates", "", ref XDoc);
            return(XDoc.ToString());
        }
コード例 #17
0
ファイル: Crypto.cs プロジェクト: LITTLELEIGE/unreal-code
        /// <summary>
        /// Parse crypto settings from INI file
        /// </summary>
        public static CryptoSettings ParseCryptoSettings(DirectoryReference InProjectDirectory, UnrealTargetPlatform InTargetPlatform)
        {
            CryptoSettings Settings = new CryptoSettings();

            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, InProjectDirectory, InTargetPlatform);

            Ini.GetBool("PlatformCrypto", "PlatformRequiresDataCrypto", out Settings.bDataCryptoRequired);

            // For now, we'll just not parse any keys if data crypto is disabled for this platform. In the future, we might want to use
            // these keys for non-data purposes (other general purpose encryption maybe?)
            if (!Settings.bDataCryptoRequired)
            {
                return(Settings);
            }

            {
                // Start by parsing the legacy encryption.ini settings
                Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InProjectDirectory, InTargetPlatform);
                Ini.GetBool("Core.Encryption", "SignPak", out Settings.bEnablePakSigning);

                string[] SigningKeyStrings = new string[3];
                Ini.GetString("Core.Encryption", "rsa.privateexp", out SigningKeyStrings[0]);
                Ini.GetString("Core.Encryption", "rsa.modulus", out SigningKeyStrings[1]);
                Ini.GetString("Core.Encryption", "rsa.publicexp", out SigningKeyStrings[2]);

                if (String.IsNullOrEmpty(SigningKeyStrings[0]) || String.IsNullOrEmpty(SigningKeyStrings[1]) || String.IsNullOrEmpty(SigningKeyStrings[2]))
                {
                    SigningKeyStrings = null;
                }
                else
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PrivateKey.Exponent = ParseHexStringToByteArray(SigningKeyStrings[0]);
                    Settings.SigningKey.PrivateKey.Modulus  = ParseHexStringToByteArray(SigningKeyStrings[1]);
                    Settings.SigningKey.PublicKey.Exponent  = ParseHexStringToByteArray(SigningKeyStrings[2]);
                    Settings.SigningKey.PublicKey.Modulus   = Settings.SigningKey.PrivateKey.Modulus;
                }

                Ini.GetBool("Core.Encryption", "EncryptPak", out Settings.bEnablePakIndexEncryption);
                Settings.bEnablePakFullAssetEncryption = false;
                Settings.bEnablePakUAssetEncryption    = false;
                Settings.bEnablePakIniEncryption       = Settings.bEnablePakIndexEncryption;

                string EncryptionKeyString;
                Ini.GetString("Core.Encryption", "aes.key", out EncryptionKeyString);
                Settings.EncryptionKey     = new EncryptionKey();
                Settings.EncryptionKey.Key = ParseAnsiStringToByteArray(EncryptionKeyString);
            }

            Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Crypto, InProjectDirectory, InTargetPlatform);
            string SectionName = "/Script/CryptoKeys.CryptoKeysSettings";
            ConfigHierarchySection CryptoSection = Ini.FindSection(SectionName);

            // If we have new format crypto keys, read them in over the top of the legacy settings
            if (CryptoSection != null && CryptoSection.KeyNames.Count() > 0)
            {
                Ini.GetBool(SectionName, "bEnablePakSigning", out Settings.bEnablePakSigning);
                Ini.GetBool(SectionName, "bEncryptPakIniFiles", out Settings.bEnablePakIniEncryption);
                Ini.GetBool(SectionName, "bEncryptPakIndex", out Settings.bEnablePakIndexEncryption);
                Ini.GetBool(SectionName, "bEncryptUAssetFiles", out Settings.bEnablePakUAssetEncryption);
                Ini.GetBool(SectionName, "bEncryptAllAssetFiles", out Settings.bEnablePakFullAssetEncryption);

                // Parse encryption key
                string EncryptionKeyString;
                Ini.GetString(SectionName, "EncryptionKey", out EncryptionKeyString);
                if (!string.IsNullOrEmpty(EncryptionKeyString))
                {
                    Settings.EncryptionKey     = new EncryptionKey();
                    Settings.EncryptionKey.Key = System.Convert.FromBase64String(EncryptionKeyString);

                    if (Settings.EncryptionKey.Key.Length != 32)
                    {
                        throw new Exception("The encryption key specified in the crypto config file must be 32 bytes long!");
                    }
                }

                // Parse signing key
                string PrivateExponent, PublicExponent, Modulus;
                Ini.GetString(SectionName, "SigningPrivateExponent", out PrivateExponent);
                Ini.GetString(SectionName, "SigningModulus", out Modulus);
                Ini.GetString(SectionName, "SigningPublicExponent", out PublicExponent);

                if (!String.IsNullOrEmpty(PrivateExponent) && !String.IsNullOrEmpty(PublicExponent) && !String.IsNullOrEmpty(Modulus))
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PublicKey.Exponent  = System.Convert.FromBase64String(PublicExponent);
                    Settings.SigningKey.PublicKey.Modulus   = System.Convert.FromBase64String(Modulus);
                    Settings.SigningKey.PrivateKey.Exponent = System.Convert.FromBase64String(PrivateExponent);
                    Settings.SigningKey.PrivateKey.Modulus  = Settings.SigningKey.PublicKey.Modulus;
                }
            }

            return(Settings);
        }
コード例 #18
0
        public string GenerateManifest(string ProjectName, bool bForDistribution, string Architecture)
        {
            ConfigHierarchy GameIni        = GetConfigCacheIni(ConfigHierarchyType.Game);
            string          ProjectVersion = string.Empty;

            GameIni.GetString("/Script/EngineSettings.GeneralProjectSettings", "ProjectVersion", out ProjectVersion);
            if (string.IsNullOrEmpty(ProjectVersion))
            {
                ProjectVersion = "1.0.0.0";
            }

            ConfigHierarchy EngineIni = GetConfigCacheIni(ConfigHierarchyType.Engine);
            Int32           VersionCode;

            EngineIni.GetInt32("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "VersionCode", out VersionCode);

            string SDKVersion             = GetMLSDKVersion(EngineIni);
            string PackageName            = GetPackageName(ProjectName);
            string ApplicationDisplayName = GetApplicationDisplayName(ProjectName);
            string MinimumAPILevel        = GetMinimumAPILevelRequired();
            string TargetExecutableName   = "bin/" + ProjectName;

            PackageManifest.version_name = ProjectVersion;
            PackageManifest.package      = PackageName;
            PackageManifest.version_code = Convert.ToUInt64(VersionCode);

            PackageManifest.application = new manifestApplication
            {
                sdk_version   = SDKVersion,
                min_api_level = MinimumAPILevel,
                visible_name  = ApplicationDisplayName
            };

            List <string> AppPrivileges;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "AppPrivileges", out AppPrivileges);

            List <string> ExtraComponentElements;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "ExtraComponentElements", out ExtraComponentElements);

            // We always add an additional item as that will be our 'root' <component>
            int Size = (ExtraComponentElements == null ? AppPrivileges.Count() : AppPrivileges.Count() + ExtraComponentElements.Count()) + 1;
            // Index used for sibling elements (app privileges, root component and any extra components)
            int CurrentIndex = 0;

            PackageManifest.application.Items = new object[Size];
            // Remove all invalid strings from the list of strings
            AppPrivileges.RemoveAll(item => item == "Invalid");
            // Privileges get added first
            for (int Index = 0; Index < AppPrivileges.Count(); ++Index)
            {
                string TrimmedPrivilege = AppPrivileges[Index].Trim(' ');
                if (TrimmedPrivilege != "")
                {
                    PackageManifest.application.Items[CurrentIndex] = new manifestApplicationUsesprivilege
                    {
                        name = TrimmedPrivilege,
                    };
                    CurrentIndex++;
                }
            }

            // Then our root component, this is important as `mldb launch` will use the first component in the manifest
            PackageManifest.application.Items[CurrentIndex] = new manifestApplicationComponent();
            manifestApplicationComponent RootComponent = (manifestApplicationComponent)PackageManifest.application.Items[CurrentIndex];

            RootComponent.name         = ".fullscreen";
            RootComponent.visible_name = ApplicationDisplayName;
            RootComponent.binary_name  = TargetExecutableName;
            RootComponent.type         = GetApplicationType();

            // Sub-elements under root <component>
            List <string> ExtraComponentSubElements;

            EngineIni.GetArray("/Script/LuminRuntimeSettings.LuminRuntimeSettings", "ExtraComponentSubElements", out ExtraComponentSubElements);
            RootComponent.Items = (ExtraComponentSubElements == null ? new object[1] : new object[ExtraComponentSubElements.Count() + 1]);

            // Root component icon
            RootComponent.Items[0] = new manifestApplicationComponentIcon();
            ((manifestApplicationComponentIcon)RootComponent.Items[0]).model_folder  = GetIconModelStagingPath();
            ((manifestApplicationComponentIcon)RootComponent.Items[0]).portal_folder = GetIconPortalStagingPath();

            if (ExtraComponentSubElements != null)
            {
                for (int Index = 0; Index < ExtraComponentSubElements.Count(); ++Index)
                {
                    Dictionary <string, string> NodeContent;
                    if (ConfigHierarchy.TryParse(ExtraComponentSubElements[Index], out NodeContent))
                    {
                        RootComponent.Items[Index + 1] = GetComponentSubElement(NodeContent["ElementType"], NodeContent["Value"]);
                    }
                }
            }

            // Finally, add additional components
            CurrentIndex++;
            if (ExtraComponentElements != null)
            {
                for (int Index = 0; Index < ExtraComponentElements.Count(); ++Index)
                {
                    Dictionary <string, string> ComponentElement;
                    if (ConfigHierarchy.TryParse(ExtraComponentElements[Index], out ComponentElement))
                    {
                        PackageManifest.application.Items[CurrentIndex] = GetComponentElement(ComponentElement);
                        CurrentIndex++;
                    }
                }
            }

            // Wrap up serialization
            XmlSerializer           PackageManifestSerializer = new XmlSerializer(PackageManifest.GetType());
            XmlSerializerNamespaces MLNamespace = new XmlSerializerNamespaces();

            MLNamespace.Add("ml", "magicleap");
            StringWriter Writer = new StringWriter();

            PackageManifestSerializer.Serialize(Writer, PackageManifest, MLNamespace);

            // allow plugins to modify final manifest HERE
            XDocument XDoc;

            try
            {
                XDoc = XDocument.Parse(Writer.ToString());
            }
            catch (Exception e)
            {
                throw new BuildException("LuminManifest.xml is invalid {0}\n{1}", e, Writer.ToString());
            }

            UPL.ProcessPluginNode(Architecture, "luminManifestUpdates", "", ref XDoc);
            return(XDoc.ToString());
        }
コード例 #19
0
        public List <string> CreateManifest(string InManifestName, string InOutputPath, string InIntermediatePath, FileReference InProjectFile, string InProjectDirectory, List <UnrealTargetConfiguration> InTargetConfigs, List <string> InExecutables)
        {
            // Verify we can find the SDK.
            string SDKDirectory = GetSDKDirectory();

            if (string.IsNullOrEmpty(SDKDirectory))
            {
                return(null);
            }

            // Check parameter values are valid.
            if (InTargetConfigs.Count != InExecutables.Count)
            {
                Log.TraceError("The number of target configurations ({0}) and executables ({1}) passed to manifest generation do not match.", InTargetConfigs.Count, InExecutables.Count);
                return(null);
            }
            if (InTargetConfigs.Count < 1)
            {
                Log.TraceError("The number of target configurations is zero, so we cannot generate a manifest.");
                return(null);
            }

            if (!CreateCheckDirectory(InOutputPath))
            {
                Log.TraceError("Failed to create output directory \"{0}\".", InOutputPath);
                return(null);
            }
            if (!CreateCheckDirectory(InIntermediatePath))
            {
                Log.TraceError("Failed to create intermediate directory \"{0}\".", InIntermediatePath);
                return(null);
            }

            OutputPath       = InOutputPath;
            IntermediatePath = InIntermediatePath;
            ProjectFile      = InProjectFile;
            ProjectPath      = InProjectDirectory;
            UpdatedFilePaths = new List <string>();

            // Load up INI settings. We'll use engine settings to retrieve the manifest configuration, but these may reference
            // values in either game or engine settings, so we'll keep both.
            GameIni   = ConfigCache.ReadHierarchy(ConfigHierarchyType.Game, DirectoryReference.FromFile(InProjectFile), ConfigPlatform);
            EngineIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(InProjectFile), ConfigPlatform);

            // Load and verify/clean culture list
            {
                List <string> CulturesToStageWithDuplicates;
                GameIni.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "CulturesToStage", out CulturesToStageWithDuplicates);
                GameIni.GetString("/Script/UnrealEd.ProjectPackagingSettings", "DefaultCulture", out DefaultCulture);
                if (CulturesToStageWithDuplicates == null || CulturesToStageWithDuplicates.Count < 1)
                {
                    Log.TraceError("At least one culture must be selected to stage.");
                    return(null);
                }

                CulturesToStage = CulturesToStageWithDuplicates.Distinct().ToList();
            }
            if (DefaultCulture == null || DefaultCulture.Length < 1)
            {
                DefaultCulture = CulturesToStage[0];
                Log.TraceWarning("A default culture must be selected to stage. Using {0}.", DefaultCulture);
            }
            if (!CulturesToStage.Contains(DefaultCulture))
            {
                DefaultCulture = CulturesToStage[0];
                Log.TraceWarning("The default culture must be one of the staged cultures. Using {0}.", DefaultCulture);
            }

            List <string> PerCultureValues;

            if (EngineIni.GetArray(IniSection_PlatformTargetSettings, "PerCultureResources", out PerCultureValues))
            {
                foreach (string CultureCombinedValues in PerCultureValues)
                {
                    Dictionary <string, string> SeparatedCultureValues;
                    if (!ConfigHierarchy.TryParse(CultureCombinedValues, out SeparatedCultureValues))
                    {
                        Log.TraceWarning("Invalid per-culture resource value: {0}", CultureCombinedValues);
                        continue;
                    }

                    string StageId      = SeparatedCultureValues["StageId"];
                    int    CultureIndex = CulturesToStage.FindIndex(x => x == StageId);
                    if (CultureIndex >= 0)
                    {
                        CulturesToStage[CultureIndex] = SeparatedCultureValues["CultureId"];
                        if (DefaultCulture == StageId)
                        {
                            DefaultCulture = SeparatedCultureValues["CultureId"];
                        }
                    }
                }
            }
            // Only warn if shipping, we can run without translated cultures they're just needed for cert
            else if (InTargetConfigs.Contains(UnrealTargetConfiguration.Shipping))
            {
                Log.TraceInformation("Staged culture mappings not setup in the editor. See Per Culture Resources in the {0} Target Settings.", Platform.ToString());
            }

            // Clean out the resources intermediate path so that we know there are no stale binary files.
            string IntermediateResourceDirectory = Path.Combine(IntermediatePath, BuildResourceSubPath);

            RecursivelyForceDeleteDirectory(IntermediateResourceDirectory);
            if (!CreateCheckDirectory(IntermediateResourceDirectory))
            {
                Log.TraceError("Could not create directory {0}.", IntermediateResourceDirectory);
                return(null);
            }

            // Construct a single resource writer for the default (no-culture) values
            string DefaultResourceIntermediatePath = Path.Combine(IntermediateResourceDirectory, "resources.resw");

            DefaultResourceWriter = new UEResXWriter(DefaultResourceIntermediatePath);

            // Construct the ResXWriters for each culture
            PerCultureResourceWriters = new Dictionary <string, UEResXWriter>();
            foreach (string Culture in CulturesToStage)
            {
                string IntermediateStringResourcePath = Path.Combine(IntermediateResourceDirectory, Culture);
                string IntermediateStringResourceFile = Path.Combine(IntermediateStringResourcePath, "resources.resw");
                if (!CreateCheckDirectory(IntermediateStringResourcePath))
                {
                    Log.TraceWarning("Culture {0} resources not staged.", Culture);
                    CulturesToStage.Remove(Culture);
                    if (Culture == DefaultCulture)
                    {
                        DefaultCulture = CulturesToStage[0];
                        Log.TraceWarning("Default culture skipped. Using {0} as default culture.", DefaultCulture);
                    }
                    continue;
                }
                PerCultureResourceWriters.Add(Culture, new UEResXWriter(IntermediateStringResourceFile));
            }



            // Create the manifest document
            string IdentityName        = null;
            var    ManifestXmlDocument = new XDocument(GetManifest(InTargetConfigs, InExecutables, out IdentityName));

            // Export manifest to the intermediate directory then compare the contents to any existing target manifest
            // and replace if there are differences.
            string ManifestIntermediatePath = Path.Combine(IntermediatePath, InManifestName);
            string ManifestTargetPath       = Path.Combine(OutputPath, InManifestName);

            ManifestXmlDocument.Save(ManifestIntermediatePath);
            CompareAndReplaceModifiedTarget(ManifestIntermediatePath, ManifestTargetPath);
            ProcessManifest(InTargetConfigs, InExecutables, InManifestName, ManifestTargetPath, ManifestIntermediatePath);

            // Clean out any resource directories that we aren't staging
            string TargetResourcePath = Path.Combine(OutputPath, BuildResourceSubPath);

            if (Directory.Exists(TargetResourcePath))
            {
                List <string> TargetResourceDirectories = new List <string>(Directory.GetDirectories(TargetResourcePath, "*.*", SearchOption.AllDirectories));
                foreach (string ResourceDirectory in TargetResourceDirectories)
                {
                    if (!CulturesToStage.Contains(Path.GetFileName(ResourceDirectory)))
                    {
                        RecursivelyForceDeleteDirectory(ResourceDirectory);
                    }
                }
            }

            // Export the resource tables starting with the default culture
            string DefaultResourceTargetPath = Path.Combine(OutputPath, BuildResourceSubPath, "resources.resw");

            DefaultResourceWriter.Close();
            CompareAndReplaceModifiedTarget(DefaultResourceIntermediatePath, DefaultResourceTargetPath);

            foreach (var Writer in PerCultureResourceWriters)
            {
                Writer.Value.Close();

                string IntermediateStringResourceFile = Path.Combine(IntermediateResourceDirectory, Writer.Key, "resources.resw");
                string TargetStringResourceFile       = Path.Combine(OutputPath, BuildResourceSubPath, Writer.Key, "resources.resw");

                CompareAndReplaceModifiedTarget(IntermediateStringResourceFile, TargetStringResourceFile);
            }

            // Copy all the binary resources into the target directory.
            CopyResourcesToTargetDir();

            // The resource database is dependent on everything else calculated here (manifest, resource string tables, binary resources).
            // So if any file has been updated we'll need to run the config.
            if (UpdatedFilePaths.Count > 0)
            {
                // Create resource index configuration
                string PriExecutable            = GetMakePriBinaryPath();
                string ResourceConfigFile       = Path.Combine(IntermediatePath, "priconfig.xml");
                bool   bEnableAutoResourcePacks = false;
                EngineIni.GetBool(IniSection_PlatformTargetSettings, "bEnableAutoResourcePacks", out bEnableAutoResourcePacks);

                // If the game is not going to support language resource packs then merge the culture qualifiers.
                if (bEnableAutoResourcePacks || CulturesToStage.Count <= 1)
                {
                    RunExternalProgram(PriExecutable, "createconfig /cf \"" + ResourceConfigFile + "\" /dq " + DefaultCulture + " /o");
                }
                else
                {
                    RunExternalProgram(PriExecutable, "createconfig /cf \"" + ResourceConfigFile + "\" /dq " + String.Join("_", CulturesToStage) + " /o");
                }

                // Modify configuration to restrict indexing to the Resources directory (saves time and space)
                XmlDocument PriConfig = new XmlDocument();
                PriConfig.Load(ResourceConfigFile);

                // If the game is not going to support resource packs then remove the autoResourcePackages.
                if (!bEnableAutoResourcePacks)
                {
                    XmlNode PackagingNode = PriConfig.SelectSingleNode("/resources/packaging");
                    PackagingNode.ParentNode.RemoveChild(PackagingNode);
                }

                // The previous implementation using startIndexAt="Resources" did not produce the expected ResourceMapSubtree hierarchy, so this manually specifies all resources in a .resfiles instead.
                string ResourcesResFile = Path.Combine(IntermediatePath, "resources.resfiles");

                XmlNode      PriIndexNode  = PriConfig.SelectSingleNode("/resources/index");
                XmlAttribute PriStartIndex = PriIndexNode.Attributes["startIndexAt"];
                PriStartIndex.Value = ResourcesResFile;

                // Swap the default folder indexer-config to a RESFILES indexer-config.
                XmlElement FolderIndexerConfigNode = PriConfig.SelectSingleNode("/resources/index/indexer-config[@type='folder']") as XmlElement;
                FolderIndexerConfigNode.SetAttribute("type", "RESFILES");
                FolderIndexerConfigNode.RemoveAttribute("foldernameAsQualifier");
                FolderIndexerConfigNode.RemoveAttribute("filenameAsQualifier");

                PriConfig.Save(ResourceConfigFile);

                IEnumerable <string>      Resources     = Directory.EnumerateFiles(Path.Combine(OutputPath, BuildResourceSubPath), "*.*", SearchOption.AllDirectories);
                System.Text.StringBuilder ResourcesList = new System.Text.StringBuilder();
                foreach (string Resource in Resources)
                {
                    ResourcesList.AppendLine(Resource.Replace(OutputPath, "").TrimStart('\\'));
                }
                File.WriteAllText(ResourcesResFile, ResourcesList.ToString());

                // Remove previous pri files so we can enumerate which ones are new since the resource generator could produce a file for each staged language.
                IEnumerable <string> OldPriFiles = Directory.EnumerateFiles(IntermediatePath, "*.pri");
                foreach (string OldPri in OldPriFiles)
                {
                    try
                    {
                        File.Delete(OldPri);
                    }
                    catch (Exception)
                    {
                        Log.TraceError("Could not delete file {0}.", OldPri);
                    }
                }

                // Generate the resource index
                string ResourceLogFile   = Path.Combine(IntermediatePath, "ResIndexLog.xml");
                string ResourceIndexFile = Path.Combine(IntermediatePath, "resources.pri");

                string MakePriCommandLine = "new /pr \"" + OutputPath + "\" /cf \"" + ResourceConfigFile + "\" /mn \"" + ManifestTargetPath + "\" /il \"" + ResourceLogFile + "\" /of \"" + ResourceIndexFile + "\" /o";

                if (IdentityName != null)
                {
                    MakePriCommandLine += " /indexName \"" + IdentityName + "\"";
                }
                RunExternalProgram(PriExecutable, MakePriCommandLine);

                // Remove any existing pri target files that were not generated by this latest update
                IEnumerable <string> NewPriFiles    = Directory.EnumerateFiles(IntermediatePath, "*.pri");
                IEnumerable <string> TargetPriFiles = Directory.EnumerateFiles(OutputPath, "*.pri");
                foreach (string TargetPri in TargetPriFiles)
                {
                    if (!NewPriFiles.Contains(TargetPri))
                    {
                        try
                        {
                            File.Delete(TargetPri);
                        }
                        catch (Exception)
                        {
                            Log.TraceError("Could not remove stale file {0}.", TargetPri);
                        }
                    }
                }

                // Stage all the modified pri files to the output directory
                foreach (string NewPri in NewPriFiles)
                {
                    string NewResourceIndexFile   = Path.Combine(IntermediatePath, Path.GetFileName(NewPri));
                    string FinalResourceIndexFile = Path.Combine(OutputPath, Path.GetFileName(NewPri));
                    CompareAndReplaceModifiedTarget(NewResourceIndexFile, FinalResourceIndexFile);
                }
            }

            return(UpdatedFilePaths);
        }
コード例 #20
0
ファイル: UEDeployTVOS.cs プロジェクト: tianjiyuan/UBTEnv
        public static bool GenerateTVOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, bool bIsClient, string ProjectName, string InEngineDir, string AppDirectory, UnrealPluginLanguage UPL, string BundleID)
        {
            // @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?
            DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory);
            ConfigHierarchy    Ini    = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirRef, UnrealTargetPlatform.IOS);

            // 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);
            if (!string.IsNullOrEmpty(BundleID))
            {
                BundleIdentifier = BundleID;
            }

            // 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("&", "&amp;");
            FinalDisplayName = FinalDisplayName.Replace("\"", "&quot;");
            FinalDisplayName = FinalDisplayName.Replace("\'", "&apos;");
            FinalDisplayName = FinalDisplayName.Replace("<", "&lt;");
            FinalDisplayName = FinalDisplayName.Replace(">", "&gt;");

            // 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>");
            string BundleExecutable = bIsUE4Game ?
                                      (bIsClient ? "UE4Client" : "UE4Game") :
                                      (bIsClient ? GameName + "Client" : GameName);

            Text.AppendLine(string.Format("\t<string>{0}</string>", BundleExecutable));
            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, InEngineDir)));
            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>Top Shelf Image</string>");
            Text.AppendLine("\t\t<key>TVTopShelfPrimaryImageWide</key>");
            Text.AppendLine("\t\t<string>Top Shelf Image Wide</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>Launch Image</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>App Icon</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);
             *                  }
             *              }
             *          }*/
            // write the iCloud container identifier, if present in the old file
            if (!string.IsNullOrEmpty(OldPListData))
            {
                int index = OldPListData.IndexOf("ICloudContainerIdentifier");
                if (index > 0)
                {
                    index = OldPListData.IndexOf("<string>", index) + 8;
                    int    length = OldPListData.IndexOf("</string>", index) - index;
                    string ICloudContainerIdentifier = OldPListData.Substring(index, length);
                    Text.AppendLine("\t<key>ICloudContainerIdentifier</key>");
                    Text.AppendLine(string.Format("\t<string>{0}</string>", ICloudContainerIdentifier));
                }
            }

            Text.AppendLine("</dict>");
            Text.AppendLine("</plist>");

            // Create the intermediate directory if needed
            if (!Directory.Exists(IntermediateDirectory))
            {
                Directory.CreateDirectory(IntermediateDirectory);
            }

            if (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 = "";
                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);
        }
コード例 #21
0
        public static bool GenerateTVOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, bool bIsClient, string ProjectName, string InEngineDir, string AppDirectory, UnrealPluginLanguage UPL, string BundleID)
        {
            // @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) : "";

            // get the settings from the ini file
            // plist replacements
            // @todo tvos: Are we going to make TVOS specific .ini files?
            DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory);
            ConfigHierarchy    Ini    = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirRef, UnrealTargetPlatform.IOS);

            // 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);
            if (!string.IsNullOrEmpty(BundleID))
            {
                BundleIdentifier = BundleID;
            }

            // 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("&", "&amp;");
            FinalDisplayName = FinalDisplayName.Replace("\"", "&quot;");
            FinalDisplayName = FinalDisplayName.Replace("\'", "&apos;");
            FinalDisplayName = FinalDisplayName.Replace("<", "&lt;");
            FinalDisplayName = FinalDisplayName.Replace(">", "&gt;");

            // 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>");
            string BundleExecutable = bIsUE4Game ?
                                      (bIsClient ? "UE4Client" : "UE4Game") :
                                      (bIsClient ? GameName + "Client" : GameName);

            Text.AppendLine(string.Format("\t<string>{0}</string>", BundleExecutable));
            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, InEngineDir)));
            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>Top Shelf Image</string>");
            Text.AppendLine("\t\t<key>TVTopShelfPrimaryImageWide</key>");
            Text.AppendLine("\t\t<string>Top Shelf Image Wide</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<string>App Icon</string>");
            Text.AppendLine("\t</dict>");
            Text.AppendLine("\t<key>UILaunchStoryboardName</key>");
            Text.AppendLine("\t<string>LaunchScreen</string>");

            // write the iCloud container identifier, if present in the old file
            if (!string.IsNullOrEmpty(OldPListData))
            {
                int index = OldPListData.IndexOf("ICloudContainerIdentifier");
                if (index > 0)
                {
                    index = OldPListData.IndexOf("<string>", index) + 8;
                    int    length = OldPListData.IndexOf("</string>", index) - index;
                    string ICloudContainerIdentifier = OldPListData.Substring(index, length);
                    Text.AppendLine("\t<key>ICloudContainerIdentifier</key>");
                    Text.AppendLine(string.Format("\t<string>{0}</string>", ICloudContainerIdentifier));
                }
            }

            Text.AppendLine("</dict>");
            Text.AppendLine("</plist>");

            // Create the intermediate directory if needed
            if (!Directory.Exists(IntermediateDirectory))
            {
                Directory.CreateDirectory(IntermediateDirectory);
            }

            if (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 = "";
                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);
        }