using System; using System.Linq; using StardewModdingAPI.Framework.ModData; using StardewModdingAPI.Toolkit.Framework.Clients.WebApi; namespace StardewModdingAPI.Framework.ModLoading { /// Metadata for a mod. internal class ModMetadata : IModMetadata { /********* ** Accessors *********/ /// The mod's display name. public string DisplayName { get; } /// The mod's full directory path. public string DirectoryPath { get; } /// The mod manifest. public IManifest Manifest { get; } /// Metadata about the mod from SMAPI's internal data (if any). public ParsedModDataRecord DataRecord { get; } /// The metadata resolution status. public ModMetadataStatus Status { get; private set; } /// Indicates non-error issues with the mod. public ModWarning Warnings { get; private set; } /// The reason the metadata is invalid, if any. public string Error { get; private set; } /// The mod instance (if loaded and is false). public IMod Mod { get; private set; } /// The content pack instance (if loaded and is true). public IContentPack ContentPack { get; private set; } /// Writes messages to the console and log file as this mod. public IMonitor Monitor { get; private set; } /// The mod-provided API (if any). public object Api { get; private set; } /// The update-check metadata for this mod (if any). public ModEntryModel UpdateCheckData { get; private set; } /// Whether the mod is a content pack. public bool IsContentPack => this.Manifest?.ContentPackFor != null; /********* ** Public methods *********/ /// Construct an instance. /// The mod's display name. /// The mod's full directory path. /// The mod manifest. /// Metadata about the mod from SMAPI's internal data (if any). public ModMetadata(string displayName, string directoryPath, IManifest manifest, ParsedModDataRecord dataRecord) { this.DisplayName = displayName; this.DirectoryPath = directoryPath; this.Manifest = manifest; this.DataRecord = dataRecord; } /// Set the mod status. /// The metadata resolution status. /// The reason the metadata is invalid, if any. /// Return the instance for chaining. public IModMetadata SetStatus(ModMetadataStatus status, string error = null) { this.Status = status; this.Error = error; return this; } /// Set a warning flag for the mod. /// The warning to set. public IModMetadata SetWarning(ModWarning warning) { this.Warnings |= warning; return this; } /// Set the mod instance. /// The mod instance to set. public IModMetadata SetMod(IMod mod) { if (this.ContentPack != null) throw new InvalidOperationException("A mod can't be both an assembly mod and content pack."); this.Mod = mod; this.Monitor = mod.Monitor; return this; } /// Set the mod instance. /// The contentPack instance to set. /// Writes messages to the console and log file. public IModMetadata SetMod(IContentPack contentPack, IMonitor monitor) { if (this.Mod != null) throw new InvalidOperationException("A mod can't be both an assembly mod and content pack."); this.ContentPack = contentPack; this.Monitor = monitor; return this; } /// Set the mod-provided API instance. /// The mod-provided API. public IModMetadata SetApi(object api) { this.Api = api; return this; } /// Set the update-check metadata for this mod. /// The update-check metadata. public IModMetadata SetUpdateData(ModEntryModel data) { this.UpdateCheckData = data; return this; } /// Whether the mod manifest was loaded (regardless of whether the mod itself was loaded). public bool HasManifest() { return this.Manifest != null; } /// Whether the mod has at least one update key set. public bool HasUpdateKeys() { return this.HasManifest() && this.Manifest.UpdateKeys != null && this.Manifest.UpdateKeys.Any(key => !string.IsNullOrWhiteSpace(key)); } } }