// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using EpicGames.Core; namespace UnrealBuildTool { /// /// Representation of a reference to a plugin from a project file /// [DebuggerDisplay("Name={Name}")] public class PluginReferenceDescriptor { /// /// Name of the plugin /// public string Name; /// /// Whether it should be enabled by default /// public bool bEnabled; /// /// Whether this plugin is optional, and the game should silently ignore it not being present /// public bool bOptional; /// /// Description of the plugin for users that do not have it installed. /// public string? Description; /// /// URL for this plugin on the marketplace, if the user doesn't have it installed. /// public string? MarketplaceURL; /// /// If enabled, list of platforms for which the plugin should be enabled (or all platforms if blank). /// public string[]? WhitelistPlatforms; /// /// If enabled, list of platforms for which the plugin should be disabled. /// public string[]? BlacklistPlatforms; /// /// If enabled, list of target configurations for which the plugin should be enabled (or all target configurations if blank). /// public UnrealTargetConfiguration[]? WhitelistTargetConfigurations; /// /// If enabled, list of target configurations for which the plugin should be disabled. /// public UnrealTargetConfiguration[]? BlacklistTargetConfigurations; /// /// If enabled, list of targets for which the plugin should be enabled (or all targets if blank). /// public TargetType[]? WhitelistTargets; /// /// If enabled, list of targets for which the plugin should be disabled. /// public TargetType[]? BlacklistTargets; /// /// The list of supported platforms for this plugin. This field is copied from the plugin descriptor, and supplements the user's whitelisted and blacklisted platforms. /// public string[]? SupportedTargetPlatforms; /// /// When true, empty SupportedTargetPlatforms and WhitelistPlatforms are interpeted as 'no platforms' with the expectation that explict platforms will be added in plugin platform extensions /// public bool bHasExplicitPlatforms; /// /// Constructor /// /// Name of the plugin /// The marketplace URL for plugins which are not installed /// Whether the plugin is enabled public PluginReferenceDescriptor(string InName, string? InMarketplaceURL, bool bInEnabled) { Name = InName; MarketplaceURL = InMarketplaceURL; bEnabled = bInEnabled; } /// /// Construct a PluginReferenceDescriptor from a Json object /// /// The writer for output fields public void Write(JsonWriter Writer) { Writer.WriteObjectStart(); Writer.WriteValue("Name", Name); Writer.WriteValue("Enabled", bEnabled); if(bEnabled && bOptional) { Writer.WriteValue("Optional", bOptional); } if(!String.IsNullOrEmpty(Description)) { Writer.WriteValue("Description", Description); } if(!String.IsNullOrEmpty(MarketplaceURL)) { Writer.WriteValue("MarketplaceURL", MarketplaceURL); } if(WhitelistPlatforms != null && WhitelistPlatforms.Length > 0) { Writer.WriteStringArrayField("WhitelistPlatforms", WhitelistPlatforms.Select(x => x.ToString()).ToArray()); } if(BlacklistPlatforms != null && BlacklistPlatforms.Length > 0) { Writer.WriteStringArrayField("BlacklistPlatforms", BlacklistPlatforms.Select(x => x.ToString()).ToArray()); } if (WhitelistTargetConfigurations != null && WhitelistTargetConfigurations.Length > 0) { Writer.WriteEnumArrayField("WhitelistTargetConfigurations", WhitelistTargetConfigurations); } if (BlacklistTargetConfigurations != null && BlacklistTargetConfigurations.Length > 0) { Writer.WriteEnumArrayField("BlacklistTargetConfigurations", BlacklistTargetConfigurations); } if (WhitelistTargets != null && WhitelistTargets.Length > 0) { Writer.WriteEnumArrayField("WhitelistTargets", WhitelistTargets); } if(BlacklistTargets != null && BlacklistTargets.Length > 0) { Writer.WriteEnumArrayField("BlacklistTargets", BlacklistTargets); } if(SupportedTargetPlatforms != null && SupportedTargetPlatforms.Length > 0) { Writer.WriteStringArrayField("SupportedTargetPlatforms", SupportedTargetPlatforms.Select(x => x.ToString()).ToArray()); } if(bHasExplicitPlatforms) { Writer.WriteValue("HasExplicitPlatforms",bHasExplicitPlatforms); } Writer.WriteObjectEnd(); } /// /// Write an array of module descriptors /// /// The Json writer to output to /// Name of the array /// Array of plugins public static void WriteArray(JsonWriter Writer, string Name, PluginReferenceDescriptor[]? Plugins) { if (Plugins != null && Plugins.Length > 0) { Writer.WriteArrayStart(Name); foreach (PluginReferenceDescriptor Plugin in Plugins) { Plugin.Write(Writer); } Writer.WriteArrayEnd(); } } /// /// Checks the given platform names array and logs a message about any that are not known. This may simply be due to not having the platform synced in Engine/Platforms/[PlatformName]. /// /// private void VerifyPlatformNames( string[]? PlatformNames ) { if (PlatformNames != null) { foreach( string PlatformName in PlatformNames ) { UnrealTargetPlatform Platform; if (!UnrealTargetPlatform.TryParse(PlatformName, out Platform)) { Log.TraceLogOnce("Ignoring unknown platform '{0}' (referenced via a project's plugin descriptor for '{1}')", PlatformName, Name ); } } } } /// /// Construct a PluginReferenceDescriptor from a Json object /// /// The Json object containing a plugin reference descriptor /// New PluginReferenceDescriptor object public static PluginReferenceDescriptor FromJsonObject(JsonObject RawObject) { 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 Descriptor.WhitelistPlatforms); RawObject.TryGetStringArrayField("BlacklistPlatforms", out Descriptor.BlacklistPlatforms); RawObject.TryGetEnumArrayField("WhitelistTargetConfigurations", out Descriptor.WhitelistTargetConfigurations); RawObject.TryGetEnumArrayField("BlacklistTargetConfigurations", out Descriptor.BlacklistTargetConfigurations); RawObject.TryGetEnumArrayField("WhitelistTargets", out Descriptor.WhitelistTargets); RawObject.TryGetEnumArrayField("BlacklistTargets", out Descriptor.BlacklistTargets); RawObject.TryGetStringArrayField("SupportedTargetPlatforms", out Descriptor.SupportedTargetPlatforms); RawObject.TryGetBoolField("HasExplicitPlatforms", out Descriptor.bHasExplicitPlatforms); Descriptor.VerifyPlatformNames(Descriptor.WhitelistPlatforms); Descriptor.VerifyPlatformNames(Descriptor.BlacklistPlatforms); Descriptor.VerifyPlatformNames(Descriptor.SupportedTargetPlatforms); } return Descriptor; } /// /// Determines if this reference enables the plugin for a given platform /// /// The platform to check /// True if the plugin should be enabled public bool IsEnabledForPlatform(UnrealTargetPlatform Platform) { if (!bEnabled) { return false; } if (bHasExplicitPlatforms) { if (WhitelistPlatforms == null || !WhitelistPlatforms.Contains(Platform.ToString())) { return false; } } else if (WhitelistPlatforms != null && WhitelistPlatforms.Length > 0 && !WhitelistPlatforms.Contains(Platform.ToString())) { return false; } if (BlacklistPlatforms != null && BlacklistPlatforms.Contains(Platform.ToString())) { return false; } return true; } /// /// Determines if this reference enables the plugin for a given target configuration /// /// The target configuration to check /// True if the plugin should be enabled public bool IsEnabledForTargetConfiguration(UnrealTargetConfiguration TargetConfiguration) { if (!bEnabled) { return false; } if (WhitelistTargetConfigurations != null && WhitelistTargetConfigurations.Length > 0 && !WhitelistTargetConfigurations.Contains(TargetConfiguration)) { return false; } if (BlacklistTargetConfigurations != null && BlacklistTargetConfigurations.Contains(TargetConfiguration)) { return false; } return true; } /// /// Determines if this reference enables the plugin for a given target /// /// The target to check /// True if the plugin should be enabled public bool IsEnabledForTarget(TargetType Target) { if (!bEnabled) { return false; } if (WhitelistTargets != null && WhitelistTargets.Length > 0 && !WhitelistTargets.Contains(Target)) { return false; } if (BlacklistTargets != null && BlacklistTargets.Contains(Target)) { return false; } return true; } /// /// Determines if this reference is valid for the given target platform. /// /// The platform to check /// True if the plugin for this target platform public bool IsSupportedTargetPlatform(UnrealTargetPlatform Platform) { if (bHasExplicitPlatforms) { return SupportedTargetPlatforms != null && SupportedTargetPlatforms.Contains(Platform.ToString()); } else { return SupportedTargetPlatforms == null || SupportedTargetPlatforms.Length == 0 || SupportedTargetPlatforms.Contains(Platform.ToString()); } } } }