public static bool LoadBundleConfig(string BundleIniFile, ref Dictionary <string, BundleSettings> Bundles)
        {
            if (System.IO.File.Exists(BundleIniFile) == false)
            {
                CommandUtils.LogWarning("Unable to find bundle config ini file  {0}", BundleIniFile);
                return(false);
            }

            FileReference BundleFileReference = new FileReference(BundleIniFile);

            ConfigHierarchy BundleConfig    = new ConfigHierarchy(new ConfigFile[] { new ConfigFile(BundleFileReference) });
            int             PriorityCounter = 0;

            foreach (string SectionName in BundleConfig.SectionNames)
            {
                BundleSettings Bundle = new BundleSettings();
                Bundle.Name     = SectionName;
                Bundle.Priority = PriorityCounter;
                ++PriorityCounter;
                {
                    string ExecFileName;
                    BundleConfig.GetString(SectionName, "ExecFileName", out ExecFileName);
                    Bundle.ExecFileName = ExecFileName;
                }
                {
                    List <string> Tags;
                    BundleConfig.GetArray(SectionName, "Tags", out Tags);
                    Bundle.Tags = Tags;
                }
                {
                    List <string> FileRegex;
                    BundleConfig.GetArray(SectionName, "FileRegex", out FileRegex);
                    Bundle.FileRegex = FileRegex;
                }
                {
                    bool bContainsShaderLibrary;
                    BundleConfig.GetBool(SectionName, "ContainsShaderLibrary", out bContainsShaderLibrary);
                    Bundle.bContainsShaderLibrary = bContainsShaderLibrary;
                }
                if (Bundle.Tags == null)
                {
                    Bundle.Tags = new List <string>();
                }

                Bundles.Add(SectionName, Bundle);
            }

            return(true);
        }
Exemplo n.º 2
0
        // Load SkookumScript.ini and return any ScriptSupportedModules specified
        public static List <string> GetSkookumScriptModuleNames(string PluginOrProjectRootDirectory, bool AddSkookumScriptRuntime = true)
        {
            List <string> moduleList = null;

            // Load SkookumScript.ini and get ScriptSupportedModules
            string iniFilePath = Path.Combine(PluginOrProjectRootDirectory, "Config/SkookumScript.ini");

            if (File.Exists(iniFilePath))
            {
                ConfigFile iniFile       = new ConfigFile(new FileReference(iniFilePath), ConfigLineAction.Add);
                var        skookumConfig = new ConfigHierarchy(new ConfigFile[] { iniFile });
                skookumConfig.GetArray("CommonSettings", "ScriptSupportedModules", out moduleList);
            }

            if (moduleList == null)
            {
                moduleList = new List <string>();
            }

            // Add additional modules needed for SkookumScript to function
            moduleList.Add("AgogCore");
            moduleList.Add("SkookumScript");
            if (AddSkookumScriptRuntime)
            {
                moduleList.Add("SkookumScriptRuntime");
            }

            return(moduleList);
        }
    private ProjectImportExportInfo GenerateProjectImportExportInfo(string RootWorkingDirectory, string LocalizationConfigFile)
    {
        ConfigFile File = new ConfigFile(new FileReference(LocalizationConfigFile), ConfigLineAction.Add);
        var        LocalizationConfig = new ConfigHierarchy(new ConfigFile[] { File });

        string DestinationPath;

        if (!LocalizationConfig.GetString("CommonSettings", "DestinationPath", out DestinationPath))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'DestinationPath', File: '{0}'", LocalizationConfigFile);
        }

        string ManifestName;

        if (!LocalizationConfig.GetString("CommonSettings", "ManifestName", out ManifestName))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'ManifestName', File: '{0}'", LocalizationConfigFile);
        }

        string ArchiveName;

        if (!LocalizationConfig.GetString("CommonSettings", "ArchiveName", out ArchiveName))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'ArchiveName', File: '{0}'", LocalizationConfigFile);
        }

        string PortableObjectName;

        if (!LocalizationConfig.GetString("CommonSettings", "PortableObjectName", out PortableObjectName))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'PortableObjectName', File: '{0}'", LocalizationConfigFile);
        }

        string NativeCulture;

        if (!LocalizationConfig.GetString("CommonSettings", "NativeCulture", out NativeCulture))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'NativeCulture', File: '{0}'", LocalizationConfigFile);
        }

        List <string> CulturesToGenerate;

        if (!LocalizationConfig.GetArray("CommonSettings", "CulturesToGenerate", out CulturesToGenerate))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'CulturesToGenerate', File: '{0}'", LocalizationConfigFile);
        }

        bool bUseCultureDirectory;

        if (!LocalizationConfig.GetBool("CommonSettings", "bUseCultureDirectory", out bUseCultureDirectory))
        {
            // bUseCultureDirectory is optional, default is true
            bUseCultureDirectory = true;
        }

        var ProjectImportExportInfo = new ProjectImportExportInfo(DestinationPath, ManifestName, ArchiveName, PortableObjectName, NativeCulture, CulturesToGenerate, bUseCultureDirectory);

        ProjectImportExportInfo.CalculateSplitPlatformNames(RootWorkingDirectory);
        return(ProjectImportExportInfo);
    }
Exemplo n.º 4
0
        public static bool HasPlatformBundleSource(DirectoryReference ProjectDir, UnrealTargetPlatform Platform)
        {
            ConfigHierarchy BundleConfig = ConfigCache.ReadHierarchy(ConfigHierarchyType.InstallBundle, ProjectDir, Platform);

            return
                (BundleConfig.GetArray("InstallBundleManager.BundleSources", "DefaultBundleSources", out List <string> InstallBundleSources) &&
                 InstallBundleSources.Contains("Platform"));
        }
Exemplo n.º 5
0
    protected void DoBuildCookRun(ProjectParams Params)
    {
        const ProjectBuildTargets ClientTargets = ProjectBuildTargets.ClientCooked | ProjectBuildTargets.ServerCooked;
        bool bGenerateNativeScripts             = Params.RunAssetNativization;
        int  WorkingCL = -1;

        if (P4Enabled && GlobalCommandLine.Submit && AllowSubmit)
        {
            WorkingCL = P4.CreateChange(P4Env.Client, String.Format("{0} build from changelist {1}", Params.ShortProjectName, P4Env.Changelist));
        }

        Project.Build(this, Params, WorkingCL, bGenerateNativeScripts ? (ProjectBuildTargets.All & ~ClientTargets) : ProjectBuildTargets.All);
        Project.Cook(Params);
        if (bGenerateNativeScripts)
        {
            // crash reporter is built along with client targets, so we need to
            // include that target flag here as well - note: that its not folded
            // into ClientTargets because the editor needs its own CrashReporter
            // as well (which would be built above)
            Project.Build(this, Params, WorkingCL, ClientTargets | ProjectBuildTargets.CrashReporter);
        }
        else
        {
            ConfigHierarchy GameIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Game, Params.RawProjectPath.Directory, HostPlatform.Current.HostEditorPlatform);
            if (GameIni != null)
            {
                List <string> NativizeBlueprintAssets                = null;
                string        BlueprintNativizationMethod            = "Disabled";
                bool          bWarnIfPackagedWithoutNativizationFlag = true;
                GameIni.GetString("/Script/UnrealEd.ProjectPackagingSettings", "BlueprintNativizationMethod", out BlueprintNativizationMethod);
                GameIni.GetBool("/Script/UnrealEd.ProjectPackagingSettings", "bWarnIfPackagedWithoutNativizationFlag", out bWarnIfPackagedWithoutNativizationFlag);
                GameIni.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "NativizeBlueprintAssets", out NativizeBlueprintAssets);

                if (bWarnIfPackagedWithoutNativizationFlag && BlueprintNativizationMethod != "Disabled")
                {
                    // Warn if we're cooking without the -nativizeAssets flag, when the project settings specify a nativization method.
                    // If the "exclusive" (whitelist) method is set, we only warn if at least one asset has been selected for conversion.
                    if (BlueprintNativizationMethod != "Exclusive" || (NativizeBlueprintAssets != null && NativizeBlueprintAssets.Count > 0))
                    {
                        LogWarning("Project is configured for Blueprint nativization, but the conversion flag (-nativizeAssets) was omitted from the command line. No nativized assets have been built as a result.");
                    }
                }
            }
        }
        Project.CopyBuildToStagingDirectory(Params);
        Project.Package(Params, WorkingCL);
        Project.Archive(Params);
        Project.Deploy(Params);
        PrintRunTime();
        Project.Run(Params);

        // Check everything in!
        if (WorkingCL != -1)
        {
            int SubmittedCL;
            P4.Submit(WorkingCL, out SubmittedCL, true, true);
        }
    }
Exemplo n.º 6
0
    /// <summary>
    /// Read a list of whitelisted or blacklisted config files names from a config file
    /// </summary>
    /// <param name="Config">The config hierarchy to read from</param>
    /// <param name="SectionName">The section name</param>
    /// <param name="KeyName">The key name to read from</param>
    /// <param name="ConfigFiles">Receives a list of config file paths</param>
    private static void ReadConfigFileList(ConfigHierarchy Config, string SectionName, string KeyName, HashSet <StagedFileReference> ConfigFiles)
    {
        List <string> ConfigFileNames;

        if (Config.GetArray(SectionName, KeyName, out ConfigFileNames))
        {
            foreach (string ConfigFileName in ConfigFileNames)
            {
                ConfigFiles.Add(new StagedFileReference(ConfigFileName));
            }
        }
    }
Exemplo n.º 7
0
        /**
         * Notify stakeholders of the commandlet results
         */
        void SendCompletionMessage(bool bWasSuccessful, String MessageBody)
        {
            MailMessage Message = new System.Net.Mail.MailMessage();

            Message.Priority = MailPriority.High;
            Message.From     = new MailAddress("*****@*****.**");

            string Branch = "Unknown";

            if (P4Enabled)
            {
                Branch = P4Env.Branch;
            }

            foreach (String NextStakeHolder in StakeholdersEmailAddresses)
            {
                Message.To.Add(new MailAddress(NextStakeHolder));
            }

            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.EditorPerProjectUserSettings, DirectoryReference.FromFile(ProjectFullPath), UnrealTargetPlatform.Win64);
            List <string>   Emails;

            Ini.GetArray("RebuildlightingSettings", "EmailNotification", out Emails);
            foreach (var Email in Emails)
            {
                Message.CC.Add(new MailAddress(Email));
            }

            Message.Subject = String.Format("Nightly lightmap rebuild {0} for {1}", bWasSuccessful ? "[SUCCESS]" : "[FAILED]", Branch);
            Message.Body    = MessageBody;

            /*Attachment Attach = new Attachment();
             * Message.Attachments.Add()*/
            try
            {
                                #pragma warning disable CS0618 // Mono 4.6.x obsoletes this class
                SmtpClient MailClient = new SmtpClient("smtp.epicgames.net");
                MailClient.Send(Message);
                                #pragma warning restore CS0618
            }
            catch (Exception Ex)
            {
                LogError("Failed to send notify email to {0} ({1})", String.Join(", ", StakeholdersEmailAddresses.ToArray()), Ex.Message);
            }
        }
Exemplo n.º 8
0
    private ProjectImportExportInfo GenerateProjectImportExportInfo(string LocalizationConfigFile)
    {
        var ProjectImportExportInfo = new ProjectImportExportInfo();

        ConfigFile File = new ConfigFile(new FileReference(LocalizationConfigFile), ConfigLineAction.Add);
        var        LocalizationConfig = new ConfigHierarchy(new ConfigFile[] { File });

        if (!LocalizationConfig.GetString("CommonSettings", "DestinationPath", out ProjectImportExportInfo.DestinationPath))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'DestinationPath', File: '{0}'", LocalizationConfigFile);
        }

        if (!LocalizationConfig.GetString("CommonSettings", "ManifestName", out ProjectImportExportInfo.ManifestName))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'ManifestName', File: '{0}'", LocalizationConfigFile);
        }

        if (!LocalizationConfig.GetString("CommonSettings", "ArchiveName", out ProjectImportExportInfo.ArchiveName))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'ArchiveName', File: '{0}'", LocalizationConfigFile);
        }

        if (!LocalizationConfig.GetString("CommonSettings", "PortableObjectName", out ProjectImportExportInfo.PortableObjectName))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'PortableObjectName', File: '{0}'", LocalizationConfigFile);
        }

        if (!LocalizationConfig.GetString("CommonSettings", "NativeCulture", out ProjectImportExportInfo.NativeCulture))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'NativeCulture', File: '{0}'", LocalizationConfigFile);
        }

        if (!LocalizationConfig.GetArray("CommonSettings", "CulturesToGenerate", out ProjectImportExportInfo.CulturesToGenerate))
        {
            throw new AutomationException("Failed to find a required config key! Section: 'CommonSettings', Key: 'CulturesToGenerate', File: '{0}'", LocalizationConfigFile);
        }

        if (!LocalizationConfig.GetBool("CommonSettings", "bUseCultureDirectory", out ProjectImportExportInfo.bUseCultureDirectory))
        {
            // bUseCultureDirectory is optional, default is true
            ProjectImportExportInfo.bUseCultureDirectory = true;
        }

        return(ProjectImportExportInfo);
    }
Exemplo n.º 9
0
    public static void CopySharedCookedBuildForTarget(string ProjectFullPath, UnrealTargetPlatform TargetPlatform, string CookPlatform, bool bOnlyCopyAssetRegistry = false)
    {
        var LocalPath = CommandUtils.CombinePaths(Path.GetDirectoryName(ProjectFullPath), "Saved", "SharedIterativeBuild", CookPlatform);

        FileReference ProjectFileRef = new FileReference(ProjectFullPath);
        // get network location
        ConfigHierarchy Hierarchy = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(ProjectFileRef), TargetPlatform);
        List <string>   CookedBuildPaths;

        if (Hierarchy.GetArray("SharedCookedBuildSettings", "SharedCookedBuildPath", out CookedBuildPaths) == false)
        {
            CommandUtils.Log("Unable to copy shared cooked build: SharedCookedBuildPath not set in Engine.ini SharedCookedBuildSettings");
            return;
        }
        foreach (var CookedBuildPath in CookedBuildPaths)
        {
            if (CopySharedCookedBuildForTargetInternal(CookedBuildPath, CookPlatform, LocalPath, bOnlyCopyAssetRegistry) == true)
            {
                return;
            }
        }

        return;
    }
Exemplo n.º 10
0
    public DeploymentContext(
        FileReference RawProjectPathOrName,
        DirectoryReference InLocalRoot,
        DirectoryReference BaseStageDirectory,
        DirectoryReference BaseArchiveDirectory,
        Platform InSourcePlatform,
        Platform InTargetPlatform,
        List <UnrealTargetConfiguration> InTargetConfigurations,
        IEnumerable <StageTarget> InStageTargets,
        List <String> InStageExecutables,
        bool InServer,
        bool InCooked,
        bool InStageCrashReporter,
        bool InStage,
        bool InCookOnTheFly,
        bool InArchive,
        bool InProgram,
        bool IsClientInsteadOfNoEditor,
        bool InForceChunkManifests,
        bool InSeparateDebugStageDirectory
        )
    {
        bStageCrashReporter       = InStageCrashReporter;
        RawProjectPath            = RawProjectPathOrName;
        DedicatedServer           = InServer;
        LocalRoot                 = InLocalRoot;
        CookSourcePlatform        = InSourcePlatform;
        StageTargetPlatform       = InTargetPlatform;
        StageTargetConfigurations = new List <UnrealTargetConfiguration>(InTargetConfigurations);
        StageTargets              = new List <StageTarget>(InStageTargets);
        StageExecutables          = InStageExecutables;
        IsCodeBasedProject        = ProjectUtils.IsCodeBasedUProjectFile(RawProjectPath, StageTargetConfigurations);
        ShortProjectName          = ProjectUtils.GetShortProjectName(RawProjectPath);
        Stage   = InStage;
        Archive = InArchive;

        if (CookSourcePlatform != null && InCooked)
        {
            CookPlatform = CookSourcePlatform.GetCookPlatform(DedicatedServer, IsClientInsteadOfNoEditor);
        }
        else if (CookSourcePlatform != null && InProgram)
        {
            CookPlatform = CookSourcePlatform.GetCookPlatform(false, false);
        }
        else
        {
            CookPlatform = "";
        }

        if (StageTargetPlatform != null && InCooked)
        {
            FinalCookPlatform = StageTargetPlatform.GetCookPlatform(DedicatedServer, IsClientInsteadOfNoEditor);
        }
        else if (StageTargetPlatform != null && InProgram)
        {
            FinalCookPlatform = StageTargetPlatform.GetCookPlatform(false, false);
        }
        else
        {
            FinalCookPlatform = "";
        }

        PlatformDir = StageTargetPlatform.PlatformType.ToString();

        if (BaseStageDirectory != null)
        {
            StageDirectory      = DirectoryReference.Combine(BaseStageDirectory, FinalCookPlatform);
            DebugStageDirectory = InSeparateDebugStageDirectory? DirectoryReference.Combine(BaseStageDirectory, FinalCookPlatform + "Debug") : StageDirectory;
        }

        if (BaseArchiveDirectory != null)
        {
            ArchiveDirectory = DirectoryReference.Combine(BaseArchiveDirectory, FinalCookPlatform);
        }

        if (!FileReference.Exists(RawProjectPath))
        {
            throw new AutomationException("Can't find uproject file {0}.", RawProjectPathOrName);
        }

        EngineRoot  = DirectoryReference.Combine(LocalRoot, "Engine");
        ProjectRoot = RawProjectPath.Directory;

        RelativeProjectRootForStage = new StagedDirectoryReference(ShortProjectName);

        ProjectArgForCommandLines = CommandUtils.MakePathSafeToUseWithCommandLine(RawProjectPath.FullName);
        CookSourceRuntimeRootDir  = RuntimeRootDir = LocalRoot;
        RuntimeProjectRootDir     = ProjectRoot;

        if (Stage)
        {
            CommandUtils.CreateDirectory(StageDirectory.FullName);

            RuntimeRootDir            = StageDirectory;
            CookSourceRuntimeRootDir  = DirectoryReference.Combine(BaseStageDirectory, CookPlatform);
            RuntimeProjectRootDir     = DirectoryReference.Combine(StageDirectory, RelativeProjectRootForStage.Name);
            ProjectArgForCommandLines = CommandUtils.MakePathSafeToUseWithCommandLine(UProjectCommandLineArgInternalRoot + RelativeProjectRootForStage.Name + "/" + ShortProjectName + ".uproject");
        }
        if (Archive)
        {
            CommandUtils.CreateDirectory(ArchiveDirectory.FullName);
        }
        ProjectArgForCommandLines = ProjectArgForCommandLines.Replace("\\", "/");
        ProjectBinariesFolder     = DirectoryReference.Combine(ProjectUtils.GetClientProjectBinariesRootPath(RawProjectPath, TargetType.Game, IsCodeBasedProject), PlatformDir);

        // Build a list of restricted folder names. This will comprise all other restricted platforms, plus standard restricted folder names such as NoRedist, NotForLicensees, etc...
        RestrictedFolderNames.UnionWith(PlatformExports.GetPlatformFolderNames());
        foreach (UnrealTargetPlatform StagePlatform in StageTargetPlatform.GetStagePlatforms())
        {
            RestrictedFolderNames.ExceptWith(PlatformExports.GetIncludedFolderNames(StagePlatform));
        }
        RestrictedFolderNames.UnionWith(FileFilter.RestrictedFolderNames);
        RestrictedFolderNames.Remove(new FileSystemName(StageTargetPlatform.IniPlatformType.ToString()));

        // Read the game config files
        ConfigHierarchy GameConfig = ConfigCache.ReadHierarchy(ConfigHierarchyType.Game, ProjectRoot, InTargetPlatform.PlatformType);

        // Read the list of directories to remap when staging
        List <string> RemapDirectoriesList;

        if (GameConfig.GetArray("Staging", "RemapDirectories", out RemapDirectoriesList))
        {
            foreach (string RemapDirectory in RemapDirectoriesList)
            {
                Dictionary <string, string> Properties;
                if (!ConfigHierarchy.TryParse(RemapDirectory, out Properties))
                {
                    throw new AutomationException("Unable to parse '{0}'", RemapDirectory);
                }

                string FromDir;
                if (!Properties.TryGetValue("From", out FromDir))
                {
                    throw new AutomationException("Missing 'From' property in '{0}'", RemapDirectory);
                }

                string ToDir;
                if (!Properties.TryGetValue("To", out ToDir))
                {
                    throw new AutomationException("Missing 'To' property in '{0}'", RemapDirectory);
                }

                RemapDirectories.Add(Tuple.Create(new StagedDirectoryReference(FromDir), new StagedDirectoryReference(ToDir)));
            }
        }

        // Read the list of directories to whitelist from restricted folder warnings
        List <string> WhitelistDirectoriesList;

        if (GameConfig.GetArray("Staging", "WhitelistDirectories", out WhitelistDirectoriesList))
        {
            foreach (string WhitelistDirectory in WhitelistDirectoriesList)
            {
                WhitelistDirectories.Add(new StagedDirectoryReference(WhitelistDirectory));
            }
        }

        // Read the list of files which are whitelisted to be staged
        ReadConfigFileList(GameConfig, "Staging", "WhitelistConfigFiles", WhitelistConfigFiles);
        ReadConfigFileList(GameConfig, "Staging", "BlacklistConfigFiles", BlacklistConfigFiles);

        // If we were configured to use manifests across the whole project, then this platform should use manifests.
        // Otherwise, read whether we are generating chunks from the ProjectPackagingSettings ini.
        if (InForceChunkManifests)
        {
            PlatformUsesChunkManifests = true;
        }
        else
        {
            ConfigHierarchy GameIni  = ConfigCache.ReadHierarchy(ConfigHierarchyType.Game, ProjectRoot, InTargetPlatform.PlatformType);
            String          IniPath  = "/Script/UnrealEd.ProjectPackagingSettings";
            bool            bSetting = false;
            if (GameIni.GetBool(IniPath, "bGenerateChunks", out bSetting))
            {
                PlatformUsesChunkManifests = bSetting;
            }
        }
    }
Exemplo n.º 11
0
    public override void Package(ProjectParams Params, DeploymentContext SC, int WorkingCL)
    {
        LogInformation("Package {0}", Params.RawProjectPath);

        LogInformation("Setting Emscripten SDK for packaging..");
        HTML5SDKInfo.SetupEmscriptenTemp();
        HTML5SDKInfo.SetUpEmscriptenConfigFile();

        // ----------------------------------------
        // ini configurations
        ConfigHierarchy ConfigCache = UnrealBuildTool.ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(Params.RawProjectPath), UnrealTargetPlatform.HTML5);

        // Debug and Development builds are not compressed to:
        // - speed up iteration times
        // - ensure (IndexedDB) data are not cached/used
        // Shipping builds "can be":
        // - compressed
        // - (IndexedDB) cached
        string ProjectConfiguration = Params.ClientConfigsToBuild[0].ToString();

        if (ProjectConfiguration == "Shipping")
        {
            ConfigCache.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "Compressed", out Compressed);
            ConfigCache.GetBool("/Script/HTML5PlatformEditor.HTML5TargetSettings", "EnableIndexedDB", out enableIndexedDB);
        }
        LogInformation("HTML5Platform.Automation: Compressed = " + Compressed);
        LogInformation("HTML5Platform.Automation: EnableIndexedDB = " + enableIndexedDB);

        // ----------------------------------------
        // package directory
        string PackagePath = Path.Combine(Path.GetDirectoryName(Params.RawProjectPath.FullName), "Binaries", "HTML5");

        if (!Directory.Exists(PackagePath))
        {
            Directory.CreateDirectory(PackagePath);
        }
        string _ProjectNameExtra  = ProjectConfiguration != "Development" ? "-HTML5-" + ProjectConfiguration : "";
        string _ProjectFullpath   = Params.GetProjectExeForPlatform(UnrealTargetPlatform.HTML5).ToString();
        string _ProjectFilename   = Path.GetFileNameWithoutExtension(_ProjectFullpath) + _ProjectNameExtra;
        string SrcUE4GameBasename = Path.Combine(Path.GetDirectoryName(_ProjectFullpath), _ProjectFilename);
        string UE4GameBasename    = Path.Combine(PackagePath, _ProjectFilename);
        string ProjectBasename    = Path.Combine(PackagePath, Params.ShortProjectName + _ProjectNameExtra);

        // ----------------------------------------
        // packaging
        if (HTMLPakAutomation.CanCreateMapPaks(Params))
        {
            HTMLPakAutomation PakAutomation = new HTMLPakAutomation(Params, SC);

            // Create Necessary Paks.
            PakAutomation.CreateEnginePak();
            PakAutomation.CreateGamePak();
            PakAutomation.CreateContentDirectoryPak();

            // Create Emscripten Package from Necessary Paks. - This will be the VFS.
            PakAutomation.CreateEmscriptenDataPackage(PackagePath, ProjectBasename + ".data");

            // Create All Map Paks which  will be downloaded on the fly.
            PakAutomation.CreateMapPak();

            // Create Delta Paks if setup.
            List <string> Paks = new List <string>();
            ConfigCache.GetArray("/Script/HTML5PlatformEditor.HTML5TargetSettings", "LevelTransitions", out Paks);

            if (Paks != null)
            {
                foreach (var Pak in Paks)
                {
                    var    Matched = Regex.Matches(Pak, "\"[^\"]+\"", RegexOptions.IgnoreCase);
                    string MapFrom = Path.GetFileNameWithoutExtension(Matched[0].ToString().Replace("\"", ""));
                    string MapTo   = Path.GetFileNameWithoutExtension(Matched[1].ToString().Replace("\"", ""));
                    PakAutomation.CreateDeltaMapPaks(MapFrom, MapTo);
                }
            }
        }
        else
        {
            // we need to operate in the root
            string PythonPath     = HTML5SDKInfo.Python();
            string EmPackagerPath = HTML5SDKInfo.EmscriptenPackager();

            using (new ScopedEnvVar("EM_CONFIG", HTML5SDKInfo.DOT_EMSCRIPTEN))
            {
                using (new PushedDirectory(Path.Combine(Params.BaseStageDirectory, "HTML5")))
                {
                    string CmdLine = string.Format("\"{0}\" \"{1}\" --preload . --js-output=\"{1}.js\" --no-heap-copy", EmPackagerPath, ProjectBasename + ".data");
                    RunAndLog(CmdEnv, PythonPath, CmdLine);
                }
            }
        }


        // ----------------------------------------
        // copy to package directory

        // ensure the ue4game binary exists, if applicable
        if (!FileExists_NoExceptions(SrcUE4GameBasename + ".js"))
        {
            LogInformation("Failed to find game application " + SrcUE4GameBasename + ".js");
            throw new AutomationException(ExitCode.Error_MissingExecutable, "Stage Failed. Could not find application {0}. You may need to build the UE4 project with your target configuration and platform.", SrcUE4GameBasename + ".js");
        }

        if (!Params.IsCodeBasedProject)
        {
            // template project - need to copy over UE4Game.*
            File.Copy(SrcUE4GameBasename + ".wasm", UE4GameBasename + ".wasm", true);
            File.Copy(SrcUE4GameBasename + ".js", UE4GameBasename + ".js", true);
            File.Copy(SrcUE4GameBasename + ".js.symbols", UE4GameBasename + ".js.symbols", true);

            File.SetAttributes(UE4GameBasename + ".wasm", FileAttributes.Normal);
            File.SetAttributes(UE4GameBasename + ".js", FileAttributes.Normal);
            File.SetAttributes(UE4GameBasename + ".js.symbols", FileAttributes.Normal);
        }
        // else, c++ projects will compile "to" PackagePath

        // note: ( ProjectBasename + ".data" ) already created above (!HTMLPakAutomation.CanCreateMapPaks())


        // ----------------------------------------
        // generate HTML files to the package directory

        // custom HTML, JS (if any), and CSS (if any) template files
        string LocalBuildPath = CombinePaths(CmdEnv.LocalRoot, "Engine/Build/HTML5");
        string BuildPath      = Path.Combine(Path.GetDirectoryName(Params.RawProjectPath.FullName), "Build", "HTML5");
        string TemplateFile   = CombinePaths(BuildPath, "project_template.html");

        if (!File.Exists(TemplateFile))
        {
            // fall back to default UE4 template files
            BuildPath    = LocalBuildPath;
            TemplateFile = CombinePaths(BuildPath, "project_template.html");
        }
        GenerateFileFromTemplate(TemplateFile, ProjectBasename + ".html", Params, ConfigCache);

        TemplateFile = CombinePaths(BuildPath, "project_template.js");
        if (File.Exists(TemplateFile))
        {
            GenerateFileFromTemplate(TemplateFile, ProjectBasename + ".UE4.js", Params, ConfigCache);
        }

        TemplateFile = CombinePaths(BuildPath, "project_template.css");
        if (File.Exists(TemplateFile))
        {
            GenerateFileFromTemplate(TemplateFile, ProjectBasename + ".css", Params, ConfigCache);
        }


        // ----------------------------------------
        // (development) support files
        string MacBashTemplateFile = CombinePaths(LocalBuildPath, "RunMacHTML5LaunchHelper_template.command");
        string MacBashOutputFile   = Path.Combine(PackagePath, "RunMacHTML5LaunchHelper.command");
        string MonoPath            = CombinePaths(CmdEnv.LocalRoot, "Engine/Build/BatchFiles/Mac/SetupMono.sh");

        GenerateMacCommandFromTemplate(MacBashTemplateFile, MacBashOutputFile, MonoPath);
        // ........................................
        string htaccesspath = Path.Combine(PackagePath, ".htaccess");

        if (File.Exists(htaccesspath))
        {
            FileAttributes attributes = File.GetAttributes(htaccesspath);
            if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
            {
                attributes &= ~FileAttributes.ReadOnly;
                File.SetAttributes(htaccesspath, attributes);
            }
        }
        File.Copy(CombinePaths(LocalBuildPath, "htaccess_template.txt"), htaccesspath, true);


        // ----------------------------------------
        // final copies

        // Gather utlity .js files and combine into one file
        string DestinationFile = PackagePath + "/Utility.js";

        File.Delete(DestinationFile);
        // spelling this out - one file at a time (i.e. don't slurp in project_template.js)
        File.AppendAllText(DestinationFile, File.ReadAllText(CombinePaths(LocalBuildPath, "json2.js")));
        File.AppendAllText(DestinationFile, File.ReadAllText(CombinePaths(LocalBuildPath, "jstorage.js")));
        File.AppendAllText(DestinationFile, File.ReadAllText(CombinePaths(LocalBuildPath, "moz_binarystring.js")));

        if (Compressed)
        {
            LogInformation("Build configuration is " + ProjectConfiguration + ", so (gzip) compressing files for web servers.");

            // Compress all files. These are independent tasks which can be threaded.
            List <Task> CompressionTasks = new List <Task>();

            CompressionTasks.Add(Task.Factory.StartNew(() => CompressFile(UE4GameBasename + ".wasm", UE4GameBasename + ".wasmgz")));                            // main game code
            CompressionTasks.Add(Task.Factory.StartNew(() => CompressFile(UE4GameBasename + ".js", UE4GameBasename + ".jsgz")));                                // main js (emscripten)
            CompressionTasks.Add(Task.Factory.StartNew(() => CompressFile(UE4GameBasename + ".js.symbols", UE4GameBasename + ".js.symbolsgz")));                // symbols fil.
            CompressionTasks.Add(Task.Factory.StartNew(() => CompressFile(PackagePath + "/Utility.js", PackagePath + "/Utility.jsgz")));                        // Utility
            CompressionTasks.Add(Task.Factory.StartNew(() => CompressFile(ProjectBasename + ".data", ProjectBasename + ".datagz")));                            // DATA file
            CompressionTasks.Add(Task.Factory.StartNew(() => CompressFile(ProjectBasename + ".data.js", ProjectBasename + ".data.jsgz")));                      // DATA file .js driver (emscripten)
            if (File.Exists(ProjectBasename + ".UE4.js"))
            {
                CompressionTasks.Add(Task.Factory.StartNew(() => CompressFile(ProjectBasename + ".UE4.js", ProjectBasename + ".UE4.jsgz")));                            // UE4 js
            }
            if (File.Exists(ProjectBasename + ".css"))
            {
                CompressionTasks.Add(Task.Factory.StartNew(() => CompressFile(ProjectBasename + ".css", ProjectBasename + ".cssgz")));                                          // UE4 css
            }
            Task.WaitAll(CompressionTasks.ToArray());
        }
        else
        {
            LogInformation("Build configuration is " + ProjectConfiguration + ", so not compressing. Build Shipping configuration to compress files to save space.");

            // nuke old compressed files to prevent using stale files
            File.Delete(UE4GameBasename + ".wasmgz");
            File.Delete(UE4GameBasename + ".jsgz");
            File.Delete(UE4GameBasename + ".js.symbolsgz");
            File.Delete(PackagePath + "/Utility.jsgz");
            File.Delete(ProjectBasename + ".datagz");
            File.Delete(ProjectBasename + ".data.jsgz");
            File.Delete(ProjectBasename + ".UE4.jsgz");
            File.Delete(ProjectBasename + ".cssgz");
        }

        File.Copy(CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/DotNET/HTML5LaunchHelper.exe"), CombinePaths(PackagePath, "HTML5LaunchHelper.exe"), true);
//		Task.WaitAll(CompressionTasks);
        PrintRunTime();
    }
Exemplo n.º 12
0
        public static bool LoadBundleConfig(string BundleIniFile, ref Dictionary <string, BundleSettings> Bundles)
        {
            if (System.IO.File.Exists(BundleIniFile) == false)
            {
                CommandUtils.LogWarning("Unable to find bundle config ini file  {0}", BundleIniFile);
                return(false);
            }

            FileReference BundleFileReference = new FileReference(BundleIniFile);

            ConfigHierarchy BundleConfig    = new ConfigHierarchy(new ConfigFile[] { new ConfigFile(BundleFileReference) });
            int             PriorityCounter = 0;

            foreach (string SectionName in BundleConfig.SectionNames)
            {
                BundleSettings Bundle = new BundleSettings();
                Bundle.Name     = SectionName;
                Bundle.Priority = PriorityCounter;
                ++PriorityCounter;
                {
                    string OverrideName;
                    if (BundleConfig.GetString(SectionName, "OverrideName", out OverrideName))
                    {
                        Bundle.OverrideName = OverrideName;
                    }
                    else
                    {
                        Bundle.OverrideName = Bundle.Name;
                    }
                }
                {
                    string ParentName;
                    BundleConfig.GetString(SectionName, "Parent", out ParentName);
                    Bundle.ParentName = ParentName;
                }
                {
                    List <string> Tags;
                    BundleConfig.GetArray(SectionName, "Tags", out Tags);
                    Bundle.Tags = Tags;
                }
                {
                    List <string> FileRegex;
                    BundleConfig.GetArray(SectionName, "FileRegex", out FileRegex);
                    Bundle.FileRegex = FileRegex;
                }
                {
                    bool bContainsShaderLibrary;
                    BundleConfig.GetBool(SectionName, "ContainsShaderLibrary", out bContainsShaderLibrary);
                    Bundle.bContainsShaderLibrary = bContainsShaderLibrary;
                }
                if (Bundle.Tags == null)
                {
                    Bundle.Tags = new List <string>();
                }

                Bundles.Add(SectionName, Bundle);
                //BundleConfig.GetArray(SectionName, "OptionalTags", out Bundle.OptionalTags);
            }



            foreach (var BundleIt in Bundles)
            {
                BundleSettings Bundle = BundleIt.Value;
                if (Bundles.ContainsKey(Bundle.ParentName))
                {
                    BundleSettings ParentBundle = Bundles[Bundle.ParentName];
                    ParentBundle.Children.Add(Bundle);
                    Bundle.bFoundParent = true;
                }
            }
            return(true);
        }
Exemplo n.º 13
0
    private static bool FindBestSharedCookedBuild(ref string FinalCookedBuildPath, string ProjectFullPath, UnrealTargetPlatform TargetPlatform, string CookPlatform, string SharedCookedBuildCL)
    {
        string BuildRoot    = CommandUtils.P4Enabled ? CommandUtils.P4Env.Branch.Replace("/", "+") : "";
        int    CurrentCLInt = CommandUtils.P4Enabled ? CommandUtils.P4Env.Changelist : 0;

        BuildVersion Version;

        if (BuildVersion.TryRead(BuildVersion.GetDefaultFileName(), out Version))
        {
            CurrentCLInt = Version.Changelist;
            BuildRoot    = Version.BranchName;
        }
        System.GC.Collect();
        string CurrentCL = CurrentCLInt.ToString();


        FileReference ProjectFileRef = new FileReference(ProjectFullPath);
        // get network location
        ConfigHierarchy Hierarchy = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(ProjectFileRef), TargetPlatform);
        List <string>   CookedBuildPaths;

        if (Hierarchy.GetArray("SharedCookedBuildSettings", "SharedCookedBuildPath", out CookedBuildPaths) == false)
        {
            CommandUtils.LogInformation("Unable to copy shared cooked build: SharedCookedBuildPath not set in Engine.ini SharedCookedBuildSettings");
            return(false);
        }

        const string MetaDataFilename = "\\Metadata\\DevelopmentAssetRegistry.bin";


        if (SharedCookedBuildCL == "usesyncedbuild")
        {
            foreach (string CookedBuildPath in CookedBuildPaths)
            {
                if (CurrentCL == "" && FinalCookedBuildPath.Contains("[CL]"))
                {
                    CommandUtils.LogInformation("Unable to copy shared cooked build: Unable to determine CL number from P4 or UGS, and is required by SharedCookedBuildPath");
                    return(false);
                }

                if (CurrentCL == "" && FinalCookedBuildPath.Contains("[BRANCHNAME]"))
                {
                    CommandUtils.LogInformation("Unable to copy shared cooked build: Unable to determine BRANCHNAME number from P4 or UGS, and is required by SharedCookedBuildPath");
                    return(false);
                }


                FinalCookedBuildPath = FinalCookedBuildPath.Replace("[CL]", CurrentCL.ToString());
                FinalCookedBuildPath = FinalCookedBuildPath.Replace("[BRANCHNAME]", BuildRoot);
                FinalCookedBuildPath = FinalCookedBuildPath.Replace("[PLATFORM]", CookPlatform);

                // make sure that the directory and metadata file exist.  otherwise this build might not be finished yet and we should skip it
                if (Directory.Exists(FinalCookedBuildPath))
                {
                    if (File.Exists(FinalCookedBuildPath + MetaDataFilename))
                    {
                        return(true);
                    }
                }
            }
        }
        else if (SharedCookedBuildCL == "userecentbuild")
        {
            // build our CookedBUildPath into a regex which we can execute on the directories and extract info from



            string BestBuild    = null;
            int    BestCLNumber = 0;

            // find all the recent builds which are valid
            foreach (string CookedBuildPath in CookedBuildPaths)
            {
                int IndexOfFirstParam = CookedBuildPath.IndexOf("[");
                int CustomFolderStart = CookedBuildPath.LastIndexOf("\\", IndexOfFirstParam);

                string CookedBuildDirectory = CookedBuildPath.Substring(0, CustomFolderStart);

                string BuildNameWildcard = CookedBuildPath.Substring(CustomFolderStart);


                BuildNameWildcard += MetaDataFilename;

                FileFilter BuildSearch = new FileFilter();

                // we know the platform and the branch name;
                string BuildRule = BuildNameWildcard;
                BuildRule = BuildRule.Replace("[BRANCHNAME]", BuildRoot);
                BuildRule = BuildRule.Replace("[PLATFORM]", CookPlatform);

                string IncludeRule = BuildRule.Replace("[CL]", "*");
                string ForgetRule  = BuildRule.Replace("[CL]", "*-PF-*");                // get rid of any preflights from the list... they don't count because who knows what they did...

                BuildSearch.AddRule(IncludeRule);
                BuildSearch.AddRule(ForgetRule, FileFilterType.Exclude);

                List <FileReference> ValidBuilds = BuildSearch.ApplyToDirectory(new DirectoryReference(CookedBuildDirectory), false);

                // figure out what the CL is
                string BuildNameRegex = String.Format(".*{0}", CookedBuildPath.Substring(CustomFolderStart));
                BuildNameRegex = BuildNameRegex.Replace("\\", "\\\\");
                BuildNameRegex = BuildNameRegex.Replace("[BRANCHNAME]", BuildRoot);
                BuildNameRegex = BuildNameRegex.Replace("+", "\\+");
                BuildNameRegex = BuildNameRegex.Replace("[PLATFORM]", CookPlatform);
                BuildNameRegex = BuildNameRegex.Replace("[CL]", "(?<CL>.*)");

                Regex ExtractCL = new Regex(BuildNameRegex);

                foreach (FileReference ValidBuild in ValidBuilds)
                {
                    string BuildPath = ValidBuild.FullName.Replace(MetaDataFilename, "");

                    Match CLMatch = ExtractCL.Match(BuildPath);
                    if (CLMatch != null)
                    {
                        string CLNumber    = CLMatch.Result("${CL}");
                        int    CLNumberInt = int.Parse(CLNumber);
                        if (CLNumberInt <= CurrentCLInt)
                        {
                            if (CLNumberInt > BestCLNumber)
                            {
                                BestCLNumber = CLNumberInt;
                                BestBuild    = BuildPath;
                            }
                        }
                    }
                }
            }

            if (string.IsNullOrEmpty(BestBuild))
            {
                return(false);
            }

            FinalCookedBuildPath = BestBuild;
            return(true);
        }


        return(false);
    }
Exemplo n.º 14
0
        public static void LoadBundleConfig <TPlatformBundleSettings>(DirectoryReference ProjectDir, UnrealTargetPlatform Platform,
                                                                      out IReadOnlyDictionary <string, TPlatformBundleSettings> Bundles,
                                                                      Action <TPlatformBundleSettings, ConfigHierarchy, string> GetPlatformSettings)
            where TPlatformBundleSettings : BundleSettings, new()
        {
            var Results = new List <TPlatformBundleSettings>();

            ConfigHierarchy BundleConfig = ConfigCache.ReadHierarchy(ConfigHierarchyType.InstallBundle, ProjectDir, Platform);

            const string BundleDefinitionPrefix = "InstallBundleDefinition ";

            foreach (string SectionName in BundleConfig.SectionNames)
            {
                if (!SectionName.StartsWith(BundleDefinitionPrefix))
                {
                    continue;
                }

                TPlatformBundleSettings Bundle = new TPlatformBundleSettings();
                Bundle.Name = SectionName.Substring(BundleDefinitionPrefix.Length);
                {
                    int Order;
                    if (BundleConfig.GetInt32(SectionName, "Order", out Order))
                    {
                        Bundle.Order = Order;
                    }
                    else
                    {
                        Bundle.Order = int.MaxValue;
                    }
                }
                {
                    List <string> Tags;
                    if (BundleConfig.GetArray(SectionName, "Tags", out Tags))
                    {
                        Bundle.Tags = Tags;
                    }
                    else
                    {
                        Bundle.Tags = new List <string>();
                    }
                }
                {
                    List <string> Dependencies;
                    if (BundleConfig.GetArray(SectionName, "Dependencies", out Dependencies))
                    {
                        Bundle.Dependencies = Dependencies;
                    }
                    else
                    {
                        Bundle.Dependencies = new List <string>();
                    }
                }
                {
                    List <string> FileRegex;
                    if (BundleConfig.GetArray(SectionName, "FileRegex", out FileRegex))
                    {
                        Bundle.FileRegex = FileRegex;
                    }
                    else
                    {
                        Bundle.FileRegex = new List <string>();
                    }
                }
                {
                    bool bContainsShaderLibrary;
                    if (BundleConfig.GetBool(SectionName, "ContainsShaderLibrary", out bContainsShaderLibrary))
                    {
                        Bundle.bContainsShaderLibrary = bContainsShaderLibrary;
                    }
                    else
                    {
                        Bundle.bContainsShaderLibrary = false;
                    }
                }

                GetPlatformSettings(Bundle, BundleConfig, BundleDefinitionPrefix + Bundle.Name);

                Results.Add(Bundle);
            }

            // Use OrderBy and not Sort because OrderBy is stable
            Bundles = Results.OrderBy(b => b.Order).ToDictionary(b => b.Name, b => b);
        }
Exemplo n.º 15
0
        public static void LoadBundleConfig <TPlatformBundleSettings>(DirectoryReference ProjectDir, UnrealTargetPlatform Platform,
                                                                      out List <TPlatformBundleSettings> Bundles,
                                                                      Action <TPlatformBundleSettings, ConfigHierarchy, string> GetPlatformSettings)
            where TPlatformBundleSettings : BundleSettings, new()
        {
            Bundles = new List <TPlatformBundleSettings>();

            ConfigHierarchy BundleConfig = ConfigCache.ReadHierarchy(ConfigHierarchyType.InstallBundle, ProjectDir, Platform);

            const string BundleDefinitionPrefix = "InstallBundleDefinition ";

            foreach (string SectionName in BundleConfig.SectionNames)
            {
                if (!SectionName.StartsWith(BundleDefinitionPrefix))
                {
                    continue;
                }

                TPlatformBundleSettings Bundle = new TPlatformBundleSettings();
                Bundle.Name = SectionName.Substring(BundleDefinitionPrefix.Length);
                {
                    int Order;
                    if (BundleConfig.GetInt32(SectionName, "Order", out Order))
                    {
                        Bundle.Order = Order;
                    }
                    else
                    {
                        Bundle.Order = int.MaxValue;
                    }
                }
                {
                    string ExecFileName;
                    BundleConfig.GetString(SectionName, "ExecFileName", out ExecFileName);
                    Bundle.ExecFileName = ExecFileName;
                }
                {
                    List <string> Tags;
                    BundleConfig.GetArray(SectionName, "Tags", out Tags);
                    Bundle.Tags = Tags;
                }
                {
                    List <string> FileRegex;
                    BundleConfig.GetArray(SectionName, "FileRegex", out FileRegex);
                    Bundle.FileRegex = FileRegex;
                }
                {
                    bool bContainsShaderLibrary;
                    BundleConfig.GetBool(SectionName, "ContainsShaderLibrary", out bContainsShaderLibrary);
                    Bundle.bContainsShaderLibrary = bContainsShaderLibrary;
                }
                if (Bundle.Tags == null)
                {
                    Bundle.Tags = new List <string>();
                }

                GetPlatformSettings(Bundle, BundleConfig, BundleDefinitionPrefix + Bundle.Name);

                Bundles.Add(Bundle);
            }

            // Use OrderBy and not Sort because OrderBy is stable
            Bundles = Bundles.OrderBy(Bundle => Bundle.Order).ToList();
        }