public static PluginReferenceDescriptor FromJson(Dictionary<string, object> Dictionary) { PluginReferenceDescriptor Descriptor = new PluginReferenceDescriptor((string)Dictionary["Name"], (bool)Dictionary["Enabled"]); TryParsePlatformList(Dictionary, "WhitelistPlatforms", Descriptor.WhitelistPlatforms); TryParsePlatformList(Dictionary, "BlacklistPlatforms", Descriptor.BlacklistPlatforms); return Descriptor; }
/// <summary> /// Creates a plugin descriptor from a file on disk /// </summary> /// <param name="FileName">The filename to read</param> /// <returns>New plugin descriptor</returns> public static ProjectDescriptor FromFile(string FileName) { JsonObject RawObject = JsonObject.Read(FileName); try { ProjectDescriptor Descriptor = new ProjectDescriptor(); // Read the version if (!RawObject.TryGetIntegerField("FileVersion", out Descriptor.FileVersion)) { if (!RawObject.TryGetIntegerField("ProjectFileVersion", out Descriptor.FileVersion)) { throw new BuildException("Project descriptor '{0}' does not contain a valid FileVersion entry", FileName); } } // Check it's not newer than the latest version we can parse if (Descriptor.FileVersion > (int)PluginDescriptorVersion.Latest) { throw new BuildException("Project descriptor '{0}' appears to be in a newer version ({1}) of the file format that we can load (max version: {2}).", FileName, Descriptor.FileVersion, (int)ProjectDescriptorVersion.Latest); } // Read simple fields RawObject.TryGetStringField("EngineAssociation", out Descriptor.EngineAssociation); RawObject.TryGetStringField("Category", out Descriptor.Category); RawObject.TryGetStringField("Description", out Descriptor.Description); // Read the modules JsonObject[] ModulesArray; if (RawObject.TryGetObjectArrayField("Modules", out ModulesArray)) { Descriptor.Modules = Array.ConvertAll(ModulesArray, x => ModuleDescriptor.FromJsonObject(x)); } // Read the plugins JsonObject[] PluginsArray; if (RawObject.TryGetObjectArrayField("Plugins", out PluginsArray)) { Descriptor.Plugins = Array.ConvertAll(PluginsArray, x => PluginReferenceDescriptor.FromJsonObject(x)); } // Read the target platforms RawObject.TryGetStringArrayField("TargetPlatforms", out Descriptor.TargetPlatforms); // Get the sample name hash RawObject.TryGetUnsignedIntegerField("EpicSampleNameHash", out Descriptor.EpicSampleNameHash); // Read the pre and post-build steps CustomBuildSteps.TryRead(RawObject, "PreBuildSteps", out Descriptor.PreBuildSteps); CustomBuildSteps.TryRead(RawObject, "PostBuildSteps", out Descriptor.PostBuildSteps); return(Descriptor); } catch (JsonParseException ParseException) { throw new JsonParseException("{0} (in {1})", ParseException.Message, FileName); } }
public static PluginReferenceDescriptor FromJson(Dictionary <string, object> Dictionary) { PluginReferenceDescriptor Descriptor = new PluginReferenceDescriptor((string)Dictionary["Name"], (bool)Dictionary["Enabled"]); TryParsePlatformList(Dictionary, "WhitelistPlatforms", Descriptor.WhitelistPlatforms); TryParsePlatformList(Dictionary, "BlacklistPlatforms", Descriptor.BlacklistPlatforms); return(Descriptor); }
/// <summary> /// Writes the plugin descriptor to an existing Json writer /// </summary> /// <param name="Writer">The writer to receive plugin data</param> /// <param name="BaseDir">Base directory to save paths relative to</param> public void Write(JsonWriter Writer, DirectoryReference BaseDir) { Writer.WriteValue("FileVersion", (int)ProjectDescriptorVersion.Latest); Writer.WriteValue("EngineAssociation", EngineAssociation); Writer.WriteValue("Category", Category); Writer.WriteValue("Description", Description); if (DisableEnginePluginsByDefault) { Writer.WriteValue("DisableEnginePluginsByDefault", DisableEnginePluginsByDefault); } // Write the enterprise flag if (IsEnterpriseProject) { Writer.WriteValue("Enterprise", IsEnterpriseProject); } // Write the module list ModuleDescriptor.WriteArray(Writer, "Modules", Modules); // Write the plugin list PluginReferenceDescriptor.WriteArray(Writer, "Plugins", Plugins); // Write the custom module roots if (AdditionalRootDirectories.Count > 0) { Writer.WriteStringArrayField("AdditionalRootDirectories", AdditionalRootDirectories.Select(x => x.MakeRelativeTo(BaseDir).Replace(Path.DirectorySeparatorChar, '/'))); } // Write out the additional plugin directories to scan if (AdditionalPluginDirectories.Count > 0) { Writer.WriteStringArrayField("AdditionalPluginDirectories", AdditionalPluginDirectories.Select(x => x.MakeRelativeTo(BaseDir).Replace(Path.DirectorySeparatorChar, '/'))); } // Write the target platforms if (TargetPlatforms != null && TargetPlatforms.Length > 0) { Writer.WriteStringArrayField("TargetPlatforms", TargetPlatforms); } // If it's a signed sample, write the name hash if (EpicSampleNameHash != 0) { Writer.WriteValue("EpicSampleNameHash", (uint)EpicSampleNameHash); } // Write the custom build steps if (PreBuildSteps != null) { PreBuildSteps.Write(Writer, "PreBuildSteps"); } if (PostBuildSteps != null) { PostBuildSteps.Write(Writer, "PostBuildSteps"); } }
/// <summary> /// Writes the plugin descriptor to an existing Json writer /// </summary> /// <param name="Writer">The writer to receive plugin data</param> public void Write(JsonWriter Writer) { Writer.WriteValue("FileVersion", (int)ProjectDescriptorVersion.Latest); Writer.WriteValue("Version", Version); Writer.WriteValue("VersionName", VersionName); Writer.WriteValue("FriendlyName", FriendlyName); Writer.WriteValue("Description", Description); Writer.WriteValue("Category", Category); Writer.WriteValue("CreatedBy", CreatedBy); Writer.WriteValue("CreatedByURL", CreatedByURL); Writer.WriteValue("DocsURL", DocsURL); Writer.WriteValue("MarketplaceURL", MarketplaceURL); Writer.WriteValue("SupportURL", SupportURL); if (!String.IsNullOrEmpty(EngineVersion)) { Writer.WriteValue("EngineVersion", EngineVersion); } if (bEnabledByDefault.HasValue) { Writer.WriteValue("EnabledByDefault", bEnabledByDefault.Value); } Writer.WriteValue("CanContainContent", bCanContainContent); if (bIsBetaVersion) { Writer.WriteValue("IsBetaVersion", bIsBetaVersion); } if (bInstalled) { Writer.WriteValue("Installed", bInstalled); } if (bRequiresBuildPlatform) { Writer.WriteValue("RequiresBuildPlatform", bRequiresBuildPlatform); } if (SupportedTargetPlatforms != null && SupportedTargetPlatforms.Length > 0) { Writer.WriteEnumArrayField <UnrealTargetPlatform>("SupportedTargetPlatforms", SupportedTargetPlatforms); } ModuleDescriptor.WriteArray(Writer, "Modules", Modules); LocalizationTargetDescriptor.WriteArray(Writer, "LocalizationTargets", LocalizationTargets); if (PreBuildSteps != null) { PreBuildSteps.Write(Writer, "PreBuildSteps"); } if (PostBuildSteps != null) { PostBuildSteps.Write(Writer, "PostBuildSteps"); } PluginReferenceDescriptor.WriteArray(Writer, "Plugins", Plugins); }
/// <summary> /// Construct a PluginReferenceDescriptor from a Json object /// </summary> /// <param name="RawObject">The Json object containing a plugin reference descriptor</param> /// <returns>New PluginReferenceDescriptor object</returns> public static PluginReferenceDescriptor FromJsonObject(JsonObject RawObject) { PluginReferenceDescriptor Descriptor = new PluginReferenceDescriptor(RawObject.GetStringField("Name"), null, RawObject.GetBoolField("Enabled")); RawObject.TryGetStringField("Description", out Descriptor.Description); RawObject.TryGetStringField("MarketplaceURL", out Descriptor.MarketplaceURL); RawObject.TryGetEnumArrayField <UnrealTargetPlatform>("WhitelistPlatforms", out Descriptor.WhitelistPlatforms); RawObject.TryGetEnumArrayField <UnrealTargetPlatform>("BlacklistPlatforms", out Descriptor.BlacklistPlatforms); return(Descriptor); }
/// <summary> /// Saves the descriptor to disk /// </summary> /// <param name="FileName">The filename to write to</param> /// <param name="bPluginTypeEnabledByDefault">Whether the plugin is enabled by default based on its location</param> public void Save(string FileName, bool bPluginTypeEnabledByDefault) { using (JsonWriter Writer = new JsonWriter(FileName)) { Writer.WriteObjectStart(); Writer.WriteValue("FileVersion", (int)ProjectDescriptorVersion.Latest); Writer.WriteValue("Version", Version); Writer.WriteValue("VersionName", VersionName); Writer.WriteValue("FriendlyName", FriendlyName); Writer.WriteValue("Description", Description); Writer.WriteValue("Category", Category); Writer.WriteValue("CreatedBy", CreatedBy); Writer.WriteValue("CreatedByURL", CreatedByURL); Writer.WriteValue("DocsURL", DocsURL); Writer.WriteValue("MarketplaceURL", MarketplaceURL); Writer.WriteValue("SupportURL", SupportURL); if (!String.IsNullOrEmpty(EngineVersion)) { Writer.WriteValue("EngineVersion", EngineVersion); } if (bEnabledByDefault != bPluginTypeEnabledByDefault) { Writer.WriteValue("EnabledByDefault", bEnabledByDefault); } Writer.WriteValue("CanContainContent", bCanContainContent); Writer.WriteValue("IsBetaVersion", bIsBetaVersion); if (bIsMod) { Writer.WriteValue("IsMod", bIsMod); } Writer.WriteValue("Installed", bInstalled); Writer.WriteValue("RequiresBuildPlatform", bRequiresBuildPlatform); ModuleDescriptor.WriteArray(Writer, "Modules", Modules); if (PreBuildSteps != null) { PreBuildSteps.Write(Writer, "PreBuildSteps"); } if (PostBuildSteps != null) { PostBuildSteps.Write(Writer, "PostBuildSteps"); } PluginReferenceDescriptor.WriteArray(Writer, "Plugins", Plugins); Writer.WriteObjectEnd(); } }
/// <summary> /// Constructor /// </summary> /// <param name="RawObject">Raw JSON object to parse</param> public ProjectDescriptor(JsonObject RawObject) { // Read the version if (!RawObject.TryGetIntegerField("FileVersion", out FileVersion)) { if (!RawObject.TryGetIntegerField("ProjectFileVersion", out FileVersion)) { throw new BuildException("Project does not contain a valid FileVersion entry"); } } // Check it's not newer than the latest version we can parse if (FileVersion > (int)PluginDescriptorVersion.Latest) { throw new BuildException("Project descriptor appears to be in a newer version ({0}) of the file format that we can load (max version: {1}).", FileVersion, (int)ProjectDescriptorVersion.Latest); } // Read simple fields RawObject.TryGetStringField("EngineAssociation", out EngineAssociation); RawObject.TryGetStringField("Category", out Category); RawObject.TryGetStringField("Description", out Description); RawObject.TryGetBoolField("Enterprise", out IsEnterpriseProject); // Read the modules JsonObject[] ModulesArray; if (RawObject.TryGetObjectArrayField("Modules", out ModulesArray)) { Modules = Array.ConvertAll(ModulesArray, x => ModuleDescriptor.FromJsonObject(x)); } // Read the plugins JsonObject[] PluginsArray; if (RawObject.TryGetObjectArrayField("Plugins", out PluginsArray)) { Plugins = Array.ConvertAll(PluginsArray, x => PluginReferenceDescriptor.FromJsonObject(x)); } // Read the additional plugin directories RawObject.TryGetStringArrayField("AdditionalPluginDirectories", out AdditionalPluginDirectories); // Read the target platforms RawObject.TryGetStringArrayField("TargetPlatforms", out TargetPlatforms); // Get the sample name hash RawObject.TryGetUnsignedIntegerField("EpicSampleNameHash", out EpicSampleNameHash); // Read the pre and post-build steps CustomBuildSteps.TryRead(RawObject, "PreBuildSteps", out PreBuildSteps); CustomBuildSteps.TryRead(RawObject, "PostBuildSteps", out PostBuildSteps); }
/// <summary> /// Construct a PluginReferenceDescriptor from a Json object /// </summary> /// <param name="RawObject">The Json object containing a plugin reference descriptor</param> /// <returns>New PluginReferenceDescriptor object</returns> public static PluginReferenceDescriptor FromJsonObject(JsonObject RawObject) { string[] WhitelistPlatformNames = null; string[] BlacklistPlatformNames = null; string[] SupportedTargetPlatformNames = null; PluginReferenceDescriptor Descriptor = new PluginReferenceDescriptor(RawObject.GetStringField("Name"), null, RawObject.GetBoolField("Enabled")); RawObject.TryGetBoolField("Optional", out Descriptor.bOptional); RawObject.TryGetStringField("Description", out Descriptor.Description); RawObject.TryGetStringField("MarketplaceURL", out Descriptor.MarketplaceURL); // Only parse platform information if enabled if (Descriptor.bEnabled) { RawObject.TryGetStringArrayField("WhitelistPlatforms", out WhitelistPlatformNames); RawObject.TryGetStringArrayField("BlacklistPlatforms", out BlacklistPlatformNames); RawObject.TryGetEnumArrayField <UnrealTargetConfiguration>("WhitelistTargetConfigurations", out Descriptor.WhitelistTargetConfigurations); RawObject.TryGetEnumArrayField <UnrealTargetConfiguration>("BlacklistTargetConfigurations", out Descriptor.BlacklistTargetConfigurations); RawObject.TryGetEnumArrayField <TargetType>("WhitelistTargets", out Descriptor.WhitelistTargets); RawObject.TryGetEnumArrayField <TargetType>("BlacklistTargets", out Descriptor.BlacklistTargets); RawObject.TryGetStringArrayField("SupportedTargetPlatforms", out SupportedTargetPlatformNames); } try { // convert string array to UnrealTargetPlatform arrays if (WhitelistPlatformNames != null) { Descriptor.WhitelistPlatforms = WhitelistPlatformNames.Select(x => UnrealTargetPlatform.Parse(x)).ToList(); } if (BlacklistPlatformNames != null) { Descriptor.BlacklistPlatforms = BlacklistPlatformNames.Select(x => UnrealTargetPlatform.Parse(x)).ToList(); } if (SupportedTargetPlatformNames != null) { Descriptor.SupportedTargetPlatforms = SupportedTargetPlatformNames.Select(x => UnrealTargetPlatform.Parse(x)).ToList(); } } catch (BuildException Ex) { ExceptionUtils.AddContext(Ex, "while parsing PluginReferenceDescriptor {0}", Descriptor.Name); throw; } return(Descriptor); }
/// <summary> /// Writes the plugin descriptor to an existing Json writer /// </summary> /// <param name="Writer">The writer to receive plugin data</param> public void Write(JsonWriter Writer) { Writer.WriteValue("FileVersion", (int)ProjectDescriptorVersion.Latest); Writer.WriteValue("EngineAssociation", EngineAssociation); Writer.WriteValue("Category", Category); Writer.WriteValue("Description", Description); // Write the enterprise flag if (IsEnterpriseProject) { Writer.WriteValue("Enterprise", IsEnterpriseProject); } // Write the module list ModuleDescriptor.WriteArray(Writer, "Modules", Modules); // Write the plugin list PluginReferenceDescriptor.WriteArray(Writer, "Plugins", Plugins); // Write out the additional plugin directories to scan if (AdditionalPluginDirectories != null && AdditionalPluginDirectories.Length > 0) { Writer.WriteStringArrayField("AdditionalPluginDirectories", AdditionalPluginDirectories); } // Write the target platforms if (TargetPlatforms != null && TargetPlatforms.Length > 0) { Writer.WriteStringArrayField("TargetPlatforms", TargetPlatforms); } // If it's a signed sample, write the name hash if (EpicSampleNameHash != 0) { Writer.WriteValue("EpicSampleNameHash", (uint)EpicSampleNameHash); } // Write the custom build steps if (PreBuildSteps != null) { PreBuildSteps.Write(Writer, "PreBuildSteps"); } if (PostBuildSteps != null) { PostBuildSteps.Write(Writer, "PostBuildSteps"); } }
/// <summary> /// Get the project folder for the given project name /// </summary> /// <param name="InProjectName">Name of the project of interest</param> /// <returns>The project filename, empty string if not found</returns> public static List <string> GetEnabledPlugins(string ProjectFileName, List <string> DefaultEnabledPlugins, UnrealTargetPlatform Platform) { // Parse the project file string ProjectFile = File.ReadAllText(ProjectFileName); try { List <string> EnabledPlugins = new List <string>(DefaultEnabledPlugins); // Create a case-insensitive dictionary of the contents Dictionary <string, object> Descriptor = fastJSON.JSON.Instance.ToObject <Dictionary <string, object> >(ProjectFile); Descriptor = new Dictionary <string, object>(Descriptor, StringComparer.InvariantCultureIgnoreCase); // Get the list of plugins object PluginsObject; if (Descriptor.TryGetValue("Plugins", out PluginsObject)) { object[] PluginsArrayObject = (object[])PluginsObject; foreach (object PluginObject in PluginsArrayObject) { PluginReferenceDescriptor Plugin = PluginReferenceDescriptor.FromJson((Dictionary <string, object>)PluginObject); if (Plugin.IsEnabledForPlatform(Platform)) { EnabledPlugins.Add(Plugin.Name); } else { EnabledPlugins.RemoveAll(x => x.Equals(Plugin.Name, StringComparison.CurrentCultureIgnoreCase)); } } } return(EnabledPlugins); } catch (BuildException Exception) { throw new BuildException("While parsing '{0}': {1}", ProjectFileName, Exception.ToString()); } }
/// <summary> /// Construct a PluginReferenceDescriptor from a Json object /// </summary> /// <param name="RawObject">The Json object containing a plugin reference descriptor</param> /// <returns>New PluginReferenceDescriptor object</returns> public static PluginReferenceDescriptor FromJsonObject(JsonObject RawObject) { PluginReferenceDescriptor Descriptor = new PluginReferenceDescriptor(RawObject.GetStringField("Name"), null, RawObject.GetBoolField("Enabled")); RawObject.TryGetStringField("Description", out Descriptor.Description); RawObject.TryGetStringField("MarketplaceURL", out Descriptor.MarketplaceURL); RawObject.TryGetEnumArrayField<UnrealTargetPlatform>("WhitelistPlatforms", out Descriptor.WhitelistPlatforms); RawObject.TryGetEnumArrayField<UnrealTargetPlatform>("BlacklistPlatforms", out Descriptor.BlacklistPlatforms); return Descriptor; }
/// <summary> /// Reads a plugin descriptor from a json object /// </summary> /// <param name="RawObject">The object to read from</param> /// <returns>New plugin descriptor</returns> public PluginDescriptor(JsonObject RawObject) { // Read the version if (!RawObject.TryGetIntegerField("FileVersion", out FileVersion)) { if (!RawObject.TryGetIntegerField("PluginFileVersion", out FileVersion)) { throw new BuildException("Plugin descriptor does not contain a valid FileVersion entry"); } } // Check it's not newer than the latest version we can parse if (FileVersion > (int)PluginDescriptorVersion.Latest) { throw new BuildException("Plugin descriptor appears to be in a newer version ({0}) of the file format that we can load (max version: {1}).", FileVersion, (int)PluginDescriptorVersion.Latest); } // Read the other fields RawObject.TryGetIntegerField("Version", out Version); RawObject.TryGetStringField("VersionName", out VersionName); RawObject.TryGetStringField("FriendlyName", out FriendlyName); RawObject.TryGetStringField("Description", out Description); if (!RawObject.TryGetStringField("Category", out Category)) { // Category used to be called CategoryPath in .uplugin files RawObject.TryGetStringField("CategoryPath", out Category); } // Due to a difference in command line parsing between Windows and Mac, we shipped a few Mac samples containing // a category name with escaped quotes. Remove them here to make sure we can list them in the right category. if (Category != null && Category.Length >= 2 && Category.StartsWith("\"") && Category.EndsWith("\"")) { Category = Category.Substring(1, Category.Length - 2); } RawObject.TryGetStringField("CreatedBy", out CreatedBy); RawObject.TryGetStringField("CreatedByURL", out CreatedByURL); RawObject.TryGetStringField("DocsURL", out DocsURL); RawObject.TryGetStringField("MarketplaceURL", out MarketplaceURL); RawObject.TryGetStringField("SupportURL", out SupportURL); RawObject.TryGetStringField("EngineVersion", out EngineVersion); RawObject.TryGetEnumArrayField <UnrealTargetPlatform>("SupportedTargetPlatforms", out SupportedTargetPlatforms); RawObject.TryGetStringArrayField("SupportedPrograms", out SupportedPrograms); JsonObject[] ModulesArray; if (RawObject.TryGetObjectArrayField("Modules", out ModulesArray)) { Modules = Array.ConvertAll(ModulesArray, x => ModuleDescriptor.FromJsonObject(x)); } JsonObject[] LocalizationTargetsArray; if (RawObject.TryGetObjectArrayField("LocalizationTargets", out LocalizationTargetsArray)) { LocalizationTargets = Array.ConvertAll(LocalizationTargetsArray, x => LocalizationTargetDescriptor.FromJsonObject(x)); } bool bEnabledByDefaultValue; if (RawObject.TryGetBoolField("EnabledByDefault", out bEnabledByDefaultValue)) { bEnabledByDefault = bEnabledByDefaultValue; } RawObject.TryGetBoolField("CanContainContent", out bCanContainContent); RawObject.TryGetBoolField("IsBetaVersion", out bIsBetaVersion); RawObject.TryGetBoolField("Installed", out bInstalled); bool bCanBeUsedWithUnrealHeaderTool; if (RawObject.TryGetBoolField("CanBeUsedWithUnrealHeaderTool", out bCanBeUsedWithUnrealHeaderTool) && bCanBeUsedWithUnrealHeaderTool) { Array.Resize(ref SupportedPrograms, (SupportedPrograms == null)? 1 : SupportedPrograms.Length + 1); SupportedPrograms[SupportedPrograms.Length - 1] = "UnrealHeaderTool"; } RawObject.TryGetBoolField("RequiresBuildPlatform", out bRequiresBuildPlatform); CustomBuildSteps.TryRead(RawObject, "PreBuildSteps", out PreBuildSteps); CustomBuildSteps.TryRead(RawObject, "PostBuildSteps", out PostBuildSteps); JsonObject[] PluginsArray; if (RawObject.TryGetObjectArrayField("Plugins", out PluginsArray)) { Plugins = Array.ConvertAll(PluginsArray, x => PluginReferenceDescriptor.FromJsonObject(x)); } }
/// <summary> /// Writes the plugin descriptor to an existing Json writer /// </summary> /// <param name="Writer">The writer to receive plugin data</param> public void Write(JsonWriter Writer) { Writer.WriteValue("FileVersion", (int)ProjectDescriptorVersion.Latest); Writer.WriteValue("Version", Version); Writer.WriteValue("VersionName", VersionName); Writer.WriteValue("FriendlyName", FriendlyName); Writer.WriteValue("Description", Description); Writer.WriteValue("Category", Category); Writer.WriteValue("CreatedBy", CreatedBy); Writer.WriteValue("CreatedByURL", CreatedByURL); Writer.WriteValue("DocsURL", DocsURL); Writer.WriteValue("MarketplaceURL", MarketplaceURL); Writer.WriteValue("SupportURL", SupportURL); if (!String.IsNullOrEmpty(EngineVersion)) { Writer.WriteValue("EngineVersion", EngineVersion); } if (bEnabledByDefault.HasValue) { Writer.WriteValue("EnabledByDefault", bEnabledByDefault.Value); } Writer.WriteValue("CanContainContent", bCanContainContent); if (bIsBetaVersion) { Writer.WriteValue("IsBetaVersion", bIsBetaVersion); } if (bIsExperimentalVersion) { Writer.WriteValue("IsExperimentalVersion", bIsExperimentalVersion); } if (bInstalled) { Writer.WriteValue("Installed", bInstalled); } if (bRequiresBuildPlatform) { Writer.WriteValue("RequiresBuildPlatform", bRequiresBuildPlatform); } if (bExplicitlyLoaded) { Writer.WriteValue("ExplicitlyLoaded", bExplicitlyLoaded); } if (SupportedTargetPlatforms != null && SupportedTargetPlatforms.Count > 0) { Writer.WriteStringArrayField("SupportedTargetPlatforms", SupportedTargetPlatforms.Select <UnrealTargetPlatform, string>(x => x.ToString()).ToArray()); } if (SupportedPrograms != null && SupportedPrograms.Length > 0) { Writer.WriteStringArrayField("SupportedPrograms", SupportedPrograms); } if (bIsPluginExtension) { Writer.WriteValue("bIsPluginExtension", bIsPluginExtension); } if (Modules != null && Modules.Count > 0) { ModuleDescriptor.WriteArray(Writer, "Modules", Modules.ToArray()); } LocalizationTargetDescriptor.WriteArray(Writer, "LocalizationTargets", LocalizationTargets); if (PreBuildSteps != null) { PreBuildSteps.Write(Writer, "PreBuildSteps"); } if (PostBuildSteps != null) { PostBuildSteps.Write(Writer, "PostBuildSteps"); } if (Plugins != null && Plugins.Count > 0) { PluginReferenceDescriptor.WriteArray(Writer, "Plugins", Plugins.ToArray()); } }
/// <summary> /// Attempt to merge a child plugin up into a parent plugin (via file naming scheme). Very little merging happens /// but it does allow for platform extensions to extend a plugin with module files /// </summary> /// <param name="Child">Child plugin that needs to merge to a main, parent plugin</param> /// <param name="Filename">Child plugin's filename, used to determine the parent's name</param> private static void TryMergeWithParent(PluginInfo Child, FileReference Filename) { // find the parent PluginInfo Parent = null; string[] Tokens = Filename.GetFileNameWithoutAnyExtensions().Split("_".ToCharArray()); if (Tokens.Length == 2) { string ParentPluginName = Tokens[0]; foreach (KeyValuePair <DirectoryReference, List <PluginInfo> > Pair in PluginInfoCache) { Parent = Pair.Value.FirstOrDefault(x => x.Name.Equals(ParentPluginName, StringComparison.InvariantCultureIgnoreCase)); if (Parent != null) { break; } } } // did we find a parent plugin? if (Parent == null) { throw new BuildException("Child plugin {0} was not named properly. It should be in the form <ParentPlugin>_<Platform>.uplugin", Filename); } // validate child plugin file name string PlatformName = Tokens[1]; if (!IsValidChildPluginSuffix(PlatformName)) { Log.TraceWarning("Ignoring child plugin: {0} - Unknown suffix \"{1}\". Expected valid platform or group", Child.File.GetFileName(), PlatformName); return; } // add our uplugin file to the existing plugin to be used to search for modules later Parent.ChildFiles.Add(Child.File); // this should cause an error if it's invalid platform name //UnrealTargetPlatform Platform = UnrealTargetPlatform.Parse(PlatformName); // merge the supported platforms if (Child.Descriptor.SupportedTargetPlatforms != null) { if (Parent.Descriptor.SupportedTargetPlatforms == null) { Parent.Descriptor.SupportedTargetPlatforms = Child.Descriptor.SupportedTargetPlatforms; } else { Parent.Descriptor.SupportedTargetPlatforms = Parent.Descriptor.SupportedTargetPlatforms.Union(Child.Descriptor.SupportedTargetPlatforms).ToList(); } } // make sure we are whitelisted for any modules we list if (Child.Descriptor.Modules != null) { if (Parent.Descriptor.Modules == null) { Parent.Descriptor.Modules = Child.Descriptor.Modules; } else { foreach (ModuleDescriptor ChildModule in Child.Descriptor.Modules) { ModuleDescriptor ParentModule = Parent.Descriptor.Modules.FirstOrDefault(x => x.Name.Equals(ChildModule.Name) && x.Type == ChildModule.Type); if (ParentModule != null) { // merge white/blacklists (if the parent had a list, and child didn't specify a list, just add the child platform to the parent list - for white and black!) if (ChildModule.WhitelistPlatforms != null) { if (ParentModule.WhitelistPlatforms == null) { ParentModule.WhitelistPlatforms = ChildModule.WhitelistPlatforms; } else { ParentModule.WhitelistPlatforms = ParentModule.WhitelistPlatforms.Union(ChildModule.WhitelistPlatforms).ToList(); } } if (ChildModule.BlacklistPlatforms != null) { if (ParentModule.BlacklistPlatforms == null) { ParentModule.BlacklistPlatforms = ChildModule.BlacklistPlatforms; } else { ParentModule.BlacklistPlatforms = ParentModule.BlacklistPlatforms.Union(ChildModule.BlacklistPlatforms).ToList(); } } } else { Parent.Descriptor.Modules.Add(ChildModule); } } } } // make sure we are whitelisted for any plugins we list if (Child.Descriptor.Plugins != null) { if (Parent.Descriptor.Plugins == null) { Parent.Descriptor.Plugins = Child.Descriptor.Plugins; } else { foreach (PluginReferenceDescriptor ChildPluginReference in Child.Descriptor.Plugins) { PluginReferenceDescriptor ParentPluginReference = Parent.Descriptor.Plugins.FirstOrDefault(x => x.Name.Equals(ChildPluginReference.Name)); if (ParentPluginReference != null) { // we only need to whitelist the platform if the parent had a whitelist (otherwise, we could mistakenly remove all other platforms) if (ParentPluginReference.WhitelistPlatforms != null) { if (ChildPluginReference.WhitelistPlatforms != null) { ParentPluginReference.WhitelistPlatforms = ParentPluginReference.WhitelistPlatforms.Union(ChildPluginReference.WhitelistPlatforms).ToList(); } } // if we want to blacklist a platform, add it even if the parent didn't have a blacklist. this won't cause problems with other platforms if (ChildPluginReference.BlacklistPlatforms != null) { if (ParentPluginReference.BlacklistPlatforms == null) { ParentPluginReference.BlacklistPlatforms = ChildPluginReference.BlacklistPlatforms; } else { ParentPluginReference.BlacklistPlatforms = ParentPluginReference.BlacklistPlatforms.Union(ChildPluginReference.BlacklistPlatforms).ToList(); } } } else { Parent.Descriptor.Plugins.Add(ChildPluginReference); } } } } // @todo platplug: what else do we want to support merging?!? }
/// <summary> /// Creates a plugin descriptor from a file on disk /// </summary> /// <param name="FileName">The filename to read</param> /// <param name="bPluginTypeEnabledByDefault">Whether this plugin should be enabled by default based on its location</param> /// <returns>New plugin descriptor</returns> public static PluginDescriptor FromFile(FileReference FileName, bool bPluginTypeEnabledByDefault) { JsonObject RawObject = JsonObject.Read(FileName.FullName); try { PluginDescriptor Descriptor = new PluginDescriptor(); // Read the version if (!RawObject.TryGetIntegerField("FileVersion", out Descriptor.FileVersion)) { if (!RawObject.TryGetIntegerField("PluginFileVersion", out Descriptor.FileVersion)) { throw new BuildException("Plugin descriptor file '{0}' does not contain a valid FileVersion entry", FileName); } } // Check it's not newer than the latest version we can parse if (Descriptor.FileVersion > (int)PluginDescriptorVersion.Latest) { throw new BuildException("Plugin descriptor file '{0}' appears to be in a newer version ({1}) of the file format that we can load (max version: {2}).", FileName, Descriptor.FileVersion, (int)PluginDescriptorVersion.Latest); } // Read the other fields RawObject.TryGetIntegerField("Version", out Descriptor.Version); RawObject.TryGetStringField("VersionName", out Descriptor.VersionName); RawObject.TryGetStringField("FriendlyName", out Descriptor.FriendlyName); RawObject.TryGetStringField("Description", out Descriptor.Description); if (!RawObject.TryGetStringField("Category", out Descriptor.Category)) { // Category used to be called CategoryPath in .uplugin files RawObject.TryGetStringField("CategoryPath", out Descriptor.Category); } // Due to a difference in command line parsing between Windows and Mac, we shipped a few Mac samples containing // a category name with escaped quotes. Remove them here to make sure we can list them in the right category. if (Descriptor.Category != null && Descriptor.Category.Length >= 2 && Descriptor.Category.StartsWith("\"") && Descriptor.Category.EndsWith("\"")) { Descriptor.Category = Descriptor.Category.Substring(1, Descriptor.Category.Length - 2); } RawObject.TryGetStringField("CreatedBy", out Descriptor.CreatedBy); RawObject.TryGetStringField("CreatedByURL", out Descriptor.CreatedByURL); RawObject.TryGetStringField("DocsURL", out Descriptor.DocsURL); RawObject.TryGetStringField("MarketplaceURL", out Descriptor.MarketplaceURL); RawObject.TryGetStringField("SupportURL", out Descriptor.SupportURL); RawObject.TryGetStringField("EngineVersion", out Descriptor.EngineVersion); JsonObject[] ModulesArray; if (RawObject.TryGetObjectArrayField("Modules", out ModulesArray)) { Descriptor.Modules = Array.ConvertAll(ModulesArray, x => ModuleDescriptor.FromJsonObject(x)); } JsonObject[] LocalizationTargetsArray; if (RawObject.TryGetObjectArrayField("LocalizationTargets", out LocalizationTargetsArray)) { Descriptor.LocalizationTargets = Array.ConvertAll(LocalizationTargetsArray, x => LocalizationTargetDescriptor.FromJsonObject(x)); } if (!RawObject.TryGetBoolField("EnabledByDefault", out Descriptor.bEnabledByDefault)) { Descriptor.bEnabledByDefault = bPluginTypeEnabledByDefault; } RawObject.TryGetBoolField("CanContainContent", out Descriptor.bCanContainContent); RawObject.TryGetBoolField("IsBetaVersion", out Descriptor.bIsBetaVersion); RawObject.TryGetBoolField("IsMod", out Descriptor.bIsMod); RawObject.TryGetBoolField("Installed", out Descriptor.bInstalled); RawObject.TryGetBoolField("CanBeUsedWithUnrealHeaderTool", out Descriptor.bCanBeUsedWithUnrealHeaderTool); RawObject.TryGetBoolField("RequiresBuildPlatform", out Descriptor.bRequiresBuildPlatform); CustomBuildSteps.TryRead(RawObject, "PreBuildSteps", out Descriptor.PreBuildSteps); CustomBuildSteps.TryRead(RawObject, "PostBuildSteps", out Descriptor.PostBuildSteps); JsonObject[] PluginsArray; if (RawObject.TryGetObjectArrayField("Plugins", out PluginsArray)) { Descriptor.Plugins = Array.ConvertAll(PluginsArray, x => PluginReferenceDescriptor.FromJsonObject(x)); } return(Descriptor); } catch (JsonParseException ParseException) { throw new JsonParseException("{0} (in {1})", ParseException.Message, FileName); } }
/// <summary> /// Creates a plugin descriptor from a file on disk /// </summary> /// <param name="FileName">The filename to read</param> /// <returns>New plugin descriptor</returns> public static ProjectDescriptor FromFile(string FileName) { JsonObject RawObject = JsonObject.Read(FileName); try { ProjectDescriptor Descriptor = new ProjectDescriptor(); // Read the version if (!RawObject.TryGetIntegerField("FileVersion", out Descriptor.FileVersion)) { if (!RawObject.TryGetIntegerField("ProjectFileVersion", out Descriptor.FileVersion)) { throw new BuildException("Project descriptor '{0}' does not contain a valid FileVersion entry", FileName); } } // Check it's not newer than the latest version we can parse if (Descriptor.FileVersion > (int)PluginDescriptorVersion.Latest) { throw new BuildException("Project descriptor '{0}' appears to be in a newer version ({1}) of the file format that we can load (max version: {2}).", FileName, Descriptor.FileVersion, (int)ProjectDescriptorVersion.Latest); } // Read simple fields RawObject.TryGetStringField("EngineAssociation", out Descriptor.EngineAssociation); RawObject.TryGetStringField("Category", out Descriptor.Category); RawObject.TryGetStringField("Description", out Descriptor.Description); // Read the modules JsonObject[] ModulesArray; if (RawObject.TryGetObjectArrayField("Modules", out ModulesArray)) { Descriptor.Modules = Array.ConvertAll(ModulesArray, x => ModuleDescriptor.FromJsonObject(x)); } // Read the plugins JsonObject[] PluginsArray; if (RawObject.TryGetObjectArrayField("Plugins", out PluginsArray)) { Descriptor.Plugins = Array.ConvertAll(PluginsArray, x => PluginReferenceDescriptor.FromJsonObject(x)); } string[] Dirs; Descriptor.AdditionalPluginDirectories = new List <DirectoryReference>(); // Read the additional plugin directories if (RawObject.TryGetStringArrayField("AdditionalPluginDirectories", out Dirs)) { for (int Index = 0; Index < Dirs.Length; Index++) { if (Path.IsPathRooted(Dirs[Index])) { // Absolute path so create in place Descriptor.AdditionalPluginDirectories.Add(new DirectoryReference(Dirs[Index])); Log.TraceVerbose("Project ({0}) : Added additional absolute plugin directory ({1})", FileName, Dirs[Index]); } else { // This path is relative to the project path so build that out string RelativePath = Path.Combine(Path.GetDirectoryName(FileName), Dirs[Index]); Descriptor.AdditionalPluginDirectories.Add(new DirectoryReference(RelativePath)); Log.TraceVerbose("Project ({0}) : Added additional relative plugin directory ({1})", FileName, Dirs[Index]); } } } // Read the target platforms RawObject.TryGetStringArrayField("TargetPlatforms", out Descriptor.TargetPlatforms); // Get the sample name hash RawObject.TryGetUnsignedIntegerField("EpicSampleNameHash", out Descriptor.EpicSampleNameHash); // Read the pre and post-build steps CustomBuildSteps.TryRead(RawObject, "PreBuildSteps", out Descriptor.PreBuildSteps); CustomBuildSteps.TryRead(RawObject, "PostBuildSteps", out Descriptor.PostBuildSteps); return(Descriptor); } catch (JsonParseException ParseException) { throw new JsonParseException("{0} (in {1})", ParseException.Message, FileName); } }