Example #1
0
 /// <inheritdoc />
 public IModMetadata SetStatus(ModMetadataStatus status, string error = null, string errorDetails = null)
 {
     this.Status       = status;
     this.Error        = error;
     this.ErrorDetails = errorDetails;
     return(this);
 }
Example #2
0
        /*********
        ** Public methods
        *********/
        /// <summary>Get manifest metadata for each folder in the given root path.</summary>
        /// <param name="toolkit">The mod toolkit.</param>
        /// <param name="rootPath">The root path to search for mods.</param>
        /// <param name="modDatabase">Handles access to SMAPI's internal mod metadata list.</param>
        /// <returns>Returns the manifests by relative folder.</returns>
        public IEnumerable <IModMetadata> ReadManifests(ModToolkit toolkit, string rootPath, ModDatabase modDatabase)
        {
            foreach (ModFolder folder in toolkit.GetModFolders(rootPath))
            {
                Manifest manifest = folder.Manifest;

                // parse internal data record (if any)
                ModDataRecordVersionedFields dataRecord = modDatabase.Get(manifest?.UniqueID)?.GetVersionedFields(manifest);

                // apply defaults
                if (manifest != null && dataRecord != null)
                {
                    if (dataRecord.UpdateKey != null)
                    {
                        manifest.UpdateKeys = new[] { dataRecord.UpdateKey }
                    }
                    ;
                }

                // build metadata
                ModMetadataStatus status = folder.ManifestParseError == null || !folder.ShouldBeLoaded
                    ? ModMetadataStatus.Found
                    : ModMetadataStatus.Failed;
                string relativePath = PathUtilities.GetRelativePath(rootPath, folder.Directory.FullName);

                yield return(new ModMetadata(folder.DisplayName, folder.Directory.FullName, relativePath, manifest, dataRecord, isIgnored: !folder.ShouldBeLoaded)
                             .SetStatus(status, !folder.ShouldBeLoaded ? "disabled by dot convention" : folder.ManifestParseError));
            }
        }
Example #3
0
        /*********
        ** Public methods
        *********/
        /// <summary>Get manifest metadata for each folder in the given root path.</summary>
        /// <param name="toolkit">The mod toolkit.</param>
        /// <param name="rootPath">The root path to search for mods.</param>
        /// <param name="modDatabase">Handles access to SMAPI's internal mod metadata list.</param>
        /// <returns>Returns the manifests by relative folder.</returns>
        public IEnumerable <IModMetadata> ReadManifests(ModToolkit toolkit, string rootPath, ModDatabase modDatabase)
        {
            foreach (ModFolder folder in toolkit.GetModFolders(rootPath))
            {
                Manifest manifest = folder.Manifest;

                // parse internal data record (if any)
                ModDataRecordVersionedFields dataRecord = modDatabase.Get(manifest?.UniqueID)?.GetVersionedFields(manifest);

                // apply defaults
                if (manifest != null && dataRecord != null)
                {
                    if (dataRecord.UpdateKey != null)
                    {
                        manifest.UpdateKeys = new[] { dataRecord.UpdateKey }
                    }
                    ;
                }

                // build metadata
                bool shouldIgnore        = folder.Type == ModType.Ignored;
                ModMetadataStatus status = folder.ManifestParseError == ModParseError.None || shouldIgnore
                    ? ModMetadataStatus.Found
                    : ModMetadataStatus.Failed;

                yield return(new ModMetadata(folder.DisplayName, folder.Directory.FullName, rootPath, manifest, dataRecord, isIgnored: shouldIgnore)
                             .SetStatus(status, shouldIgnore ? "disabled by dot convention" : folder.ManifestParseErrorText));
            }
        }
Example #4
0
        /*********
        ** Public methods
        *********/
        /// <summary>Get manifest metadata for each folder in the given root path.</summary>
        /// <param name="toolkit">The mod toolkit.</param>
        /// <param name="rootPath">The root path to search for mods.</param>
        /// <param name="modDatabase">Handles access to SMAPI's internal mod metadata list.</param>
        /// <returns>Returns the manifests by relative folder.</returns>
        public IEnumerable <IModMetadata> ReadManifests(ModToolkit toolkit, string rootPath, ModDatabase modDatabase)
        {
            foreach (ModFolder folder in toolkit.GetModFolders(rootPath))
            {
                Manifest manifest = folder.Manifest;

                // parse internal data record (if any)
                ModDataRecordVersionedFields dataRecord = modDatabase.Get(manifest?.UniqueID)?.GetVersionedFields(manifest);

                // apply defaults
                if (manifest != null && dataRecord != null)
                {
                    if (dataRecord.UpdateKey != null)
                    {
                        manifest.UpdateKeys = new[] { dataRecord.UpdateKey }
                    }
                    ;
                }

                // build metadata
                ModMetadataStatus status = folder.ManifestParseError == null
                    ? ModMetadataStatus.Found
                    : ModMetadataStatus.Failed;
                yield return(new ModMetadata(folder.DisplayName, folder.Directory.FullName, manifest, dataRecord).SetStatus(status, folder.ManifestParseError));
            }
        }
Example #5
0
 /// <inheritdoc />
 public IModMetadata SetStatus(ModMetadataStatus status, ModFailReason reason, string error, string errorDetails = null)
 {
     this.Status       = status;
     this.FailReason   = reason;
     this.Error        = error;
     this.ErrorDetails = errorDetails;
     return(this);
 }
Example #6
0
        /*********
        ** Public methods
        *********/
        /// <summary>Get manifest metadata for each folder in the given root path.</summary>
        /// <param name="rootPath">The root path to search for mods.</param>
        /// <param name="jsonHelper">The JSON helper with which to read manifests.</param>
        /// <param name="modDatabase">Handles access to SMAPI's internal mod metadata list.</param>
        /// <returns>Returns the manifests by relative folder.</returns>
        public IEnumerable <IModMetadata> ReadManifests(string rootPath, JsonHelper jsonHelper, ModDatabase modDatabase)
        {
            foreach (DirectoryInfo modDir in this.GetModFolders(rootPath))
            {
                // read file
                Manifest manifest = null;
                string   path     = Path.Combine(modDir.FullName, "manifest.json");
                string   error    = null;
                try
                {
                    manifest = jsonHelper.ReadJsonFile <Manifest>(path);
                    if (manifest == null)
                    {
                        error = File.Exists(path)
                            ? "its manifest is invalid."
                            : "it doesn't have a manifest.";
                    }
                }
                catch (SParseException ex)
                {
                    error = $"parsing its manifest failed: {ex.Message}";
                }
                catch (Exception ex)
                {
                    error = $"parsing its manifest failed:\n{ex.GetLogSummary()}";
                }

                // parse internal data record (if any)
                ParsedModDataRecord dataRecord = modDatabase.GetParsed(manifest);

                // get display name
                string displayName = manifest?.Name;
                if (string.IsNullOrWhiteSpace(displayName))
                {
                    displayName = dataRecord?.DisplayName;
                }
                if (string.IsNullOrWhiteSpace(displayName))
                {
                    displayName = PathUtilities.GetRelativePath(rootPath, modDir.FullName);
                }

                // apply defaults
                if (manifest != null && dataRecord != null)
                {
                    if (dataRecord.UpdateKey != null)
                    {
                        manifest.UpdateKeys = new[] { dataRecord.UpdateKey }
                    }
                    ;
                }

                // build metadata
                ModMetadataStatus status = error == null
                    ? ModMetadataStatus.Found
                    : ModMetadataStatus.Failed;
                yield return(new ModMetadata(displayName, modDir.FullName, manifest, dataRecord).SetStatus(status, error));
            }
        }
Example #7
0
        /*********
        ** Public methods
        *********/
        /// <summary>Get manifest metadata for each folder in the given root path.</summary>
        /// <param name="rootPath">The root path to search for mods.</param>
        /// <param name="jsonHelper">The JSON helper with which to read manifests.</param>
        /// <param name="dataRecords">Metadata about mods from SMAPI's internal data.</param>
        /// <returns>Returns the manifests by relative folder.</returns>
        public IEnumerable <IModMetadata> ReadManifests(string rootPath, JsonHelper jsonHelper, IEnumerable <ModDataRecord> dataRecords)
        {
            dataRecords = dataRecords.ToArray();

            foreach (DirectoryInfo modDir in this.GetModFolders(rootPath))
            {
                // read file
                Manifest manifest = null;
                string   path     = Path.Combine(modDir.FullName, "manifest.json");
                string   error    = null;
                try
                {
                    // read manifest
                    manifest = jsonHelper.ReadJsonFile <Manifest>(path);

                    // validate
                    if (manifest == null)
                    {
                        error = File.Exists(path)
                            ? "its manifest is invalid."
                            : "it doesn't have a manifest.";
                    }
                    else if (string.IsNullOrWhiteSpace(manifest.EntryDll))
                    {
                        error = "its manifest doesn't set an entry DLL.";
                    }
                }
                catch (SParseException ex)
                {
                    error = $"parsing its manifest failed: {ex.Message}";
                }
                catch (Exception ex)
                {
                    error = $"parsing its manifest failed:\n{ex.GetLogSummary()}";
                }

                // validate metadata
                ModDataRecord dataRecord = null;
                if (manifest != null)
                {
                    // get unique key for lookups
                    string key = !string.IsNullOrWhiteSpace(manifest.UniqueID) ? manifest.UniqueID : manifest.EntryDll;

                    // get data record
                    dataRecord = dataRecords.FirstOrDefault(record => record.ID.Matches(key, manifest));
                }

                // build metadata
                string displayName = !string.IsNullOrWhiteSpace(manifest?.Name)
                    ? manifest.Name
                    : modDir.FullName.Replace(rootPath, "").Trim('/', '\\');
                ModMetadataStatus status = error == null
                    ? ModMetadataStatus.Found
                    : ModMetadataStatus.Failed;

                yield return(new ModMetadata(displayName, modDir.FullName, manifest, dataRecord).SetStatus(status, error));
            }
        }
Example #8
0
        /*********
        ** Public methods
        *********/
        /// <summary>Get manifest metadata for each folder in the given root path.</summary>
        /// <param name="toolkit">The mod toolkit.</param>
        /// <param name="rootPath">The root path to search for mods.</param>
        /// <param name="modDatabase">Handles access to SMAPI's internal mod metadata list.</param>
        /// <returns>Returns the manifests by relative folder.</returns>
        public IEnumerable <IModMetadata> ReadManifests(ModToolkit toolkit, string rootPath, ModDatabase modDatabase)
        {
            foreach (ModFolder folder in toolkit.GetModFolders(rootPath))
            {
                Manifest manifest = folder.Manifest;

                // parse internal data record (if any)
                ModDataRecordVersionedFields dataRecord = modDatabase.Get(manifest?.UniqueID)?.GetVersionedFields(manifest);

                // get display name
                string displayName = manifest?.Name;
                if (string.IsNullOrWhiteSpace(displayName))
                {
                    displayName = dataRecord?.DisplayName;
                }
                if (string.IsNullOrWhiteSpace(displayName))
                {
                    displayName = PathUtilities.GetRelativePath(rootPath, folder.ActualDirectory?.FullName ?? folder.SearchDirectory.FullName);
                }

                // apply defaults
                if (manifest != null && dataRecord != null)
                {
                    if (dataRecord.UpdateKey != null)
                    {
                        manifest.UpdateKeys = new[] { dataRecord.UpdateKey }
                    }
                    ;
                }

                // build metadata
                ModMetadataStatus status = folder.ManifestParseError == null
                    ? ModMetadataStatus.Found
                    : ModMetadataStatus.Failed;
                yield return(new ModMetadata(displayName, folder.ActualDirectory?.FullName, manifest, dataRecord).SetStatus(status, folder.ManifestParseError));
            }
        }
Example #9
0
        /*********
        ** Public methods
        *********/
        /// <summary>Get manifest metadata for each folder in the given root path.</summary>
        /// <param name="rootPath">The root path to search for mods.</param>
        /// <param name="jsonHelper">The JSON helper with which to read manifests.</param>
        /// <param name="compatibilityRecords">Metadata about mods that SMAPI should assume is compatible or broken, regardless of whether it detects incompatible code.</param>
        /// <param name="disabledMods">Metadata about mods that SMAPI should consider obsolete and not load.</param>
        /// <returns>Returns the manifests by relative folder.</returns>
        public IEnumerable <IModMetadata> ReadManifests(string rootPath, JsonHelper jsonHelper, IEnumerable <ModCompatibility> compatibilityRecords, IEnumerable <DisabledMod> disabledMods)
        {
            compatibilityRecords = compatibilityRecords.ToArray();
            disabledMods         = disabledMods.ToArray();

            foreach (DirectoryInfo modDir in this.GetModFolders(rootPath))
            {
                // read file
                Manifest manifest = null;
                string   path     = Path.Combine(modDir.FullName, "manifest.json");
                string   error    = null;
                try
                {
                    // read manifest
                    manifest = jsonHelper.ReadJsonFile <Manifest>(path);

                    // validate
                    if (manifest == null)
                    {
                        error = File.Exists(path)
                            ? "its manifest is invalid."
                            : "it doesn't have a manifest.";
                    }
                    else if (string.IsNullOrWhiteSpace(manifest.EntryDll))
                    {
                        error = "its manifest doesn't set an entry DLL.";
                    }
                }
                catch (SParseException ex)
                {
                    error = $"parsing its manifest failed: {ex.Message}";
                }
                catch (Exception ex)
                {
                    error = $"parsing its manifest failed:\n{ex.GetLogSummary()}";
                }

                // validate metadata
                ModCompatibility compatibility = null;
                if (manifest != null)
                {
                    // get unique key for lookups
                    string key = !string.IsNullOrWhiteSpace(manifest.UniqueID) ? manifest.UniqueID : manifest.EntryDll;

                    // check if mod should be disabled
                    DisabledMod disabledMod = disabledMods.FirstOrDefault(mod => mod.ID.Contains(key, StringComparer.InvariantCultureIgnoreCase));
                    if (disabledMod != null)
                    {
                        error = $"it's obsolete: {disabledMod.ReasonPhrase}";
                    }

                    // get compatibility record
                    compatibility = (
                        from mod in compatibilityRecords
                        where
                        mod.ID.Any(p => p.Matches(key, manifest)) &&
                        (mod.LowerVersion == null || !manifest.Version.IsOlderThan(mod.LowerVersion)) &&
                        !manifest.Version.IsNewerThan(mod.UpperVersion)
                        select mod
                        ).FirstOrDefault();
                }

                // build metadata
                string displayName = !string.IsNullOrWhiteSpace(manifest?.Name)
                    ? manifest.Name
                    : modDir.FullName.Replace(rootPath, "").Trim('/', '\\');
                ModMetadataStatus status = error == null
                    ? ModMetadataStatus.Found
                    : ModMetadataStatus.Failed;

                yield return(new ModMetadata(displayName, modDir.FullName, manifest, compatibility).SetStatus(status, error));
            }
        }
Example #10
0
 /// <summary>Set the mod status.</summary>
 /// <param name="status">The metadata resolution status.</param>
 /// <param name="error">The reason the metadata is invalid, if any.</param>
 /// <returns>Return the instance for chaining.</returns>
 public IModMetadata SetStatus(ModMetadataStatus status, string error = null)
 {
     this.Status = status;
     this.Error = error;
     return this;
 }