using System; using System.Collections.Generic; using System.Linq; namespace StardewModdingAPI.Toolkit.Framework.ModData { /// The parsed mod metadata from SMAPI's internal mod list. public class ModDataRecord { /********* ** Accessors *********/ /// The mod's default display name. public string DisplayName { get; } /// The mod's current unique ID. public string ID { get; } /// The former mod IDs (if any). public string[] FormerIDs { get; } /// The mod warnings to suppress, even if they'd normally be shown. public ModWarning SuppressWarnings { get; } /// The versioned field data. public ModDataField[] Fields { get; } /********* ** Public methods *********/ /// Construct an instance. /// The mod's default display name. /// The raw data model. internal ModDataRecord(string displayName, ModDataModel model) { this.DisplayName = displayName; this.ID = model.ID; this.FormerIDs = model.GetFormerIDs().ToArray(); this.SuppressWarnings = model.SuppressWarnings; this.Fields = model.GetFields().ToArray(); } /// Get whether the mod has (or previously had) the given ID. /// The mod ID. public bool HasID(string id) { // try main ID if (this.ID.Equals(id, StringComparison.OrdinalIgnoreCase)) return true; // try former IDs foreach (string formerID in this.FormerIDs) { if (formerID.Equals(id, StringComparison.OrdinalIgnoreCase)) return true; } return false; } /// Get the possible mod IDs. public IEnumerable GetIDs() { return this.FormerIDs .Concat(new[] { this.ID }) .Where(p => !string.IsNullOrWhiteSpace(p)) .Select(p => p.Trim()) .Distinct(); } /// Get the default update key for this mod, if any. public string? GetDefaultUpdateKey() { string? updateKey = this.Fields.FirstOrDefault(p => p.Key == ModDataFieldKey.UpdateKey && p.IsDefault)?.Value; return !string.IsNullOrWhiteSpace(updateKey) ? updateKey : null; } /// Get a parsed representation of the which match a given manifest. /// The manifest to match. public ModDataRecordVersionedFields GetVersionedFields(IManifest? manifest) { ModDataRecordVersionedFields parsed = new(this); foreach (ModDataField field in this.Fields.Where(field => field.IsMatch(manifest))) { switch (field.Key) { // update key case ModDataFieldKey.UpdateKey: parsed.UpdateKey = field.Value; break; // status case ModDataFieldKey.Status: parsed.Status = (ModStatus)Enum.Parse(typeof(ModStatus), field.Value, ignoreCase: true); parsed.StatusUpperVersion = field.UpperVersion; break; // status reason phrase case ModDataFieldKey.StatusReasonPhrase: parsed.StatusReasonPhrase = field.Value; break; // status technical reason case ModDataFieldKey.StatusReasonDetails: parsed.StatusReasonDetails = field.Value; break; } } return parsed; } } }