コード例 #1
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));
            }
        }
コード例 #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));
            }
        }
コード例 #3
0
ファイル: ModResolver.cs プロジェクト: mit4web/SMAPI
        /*********
        ** 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));
            }
        }
コード例 #4
0
 /// <summary>Set up a mock mod metadata for <see cref="ModResolver.ValidateManifests"/>.</summary>
 /// <param name="mod">The mock mod metadata.</param>
 /// <param name="modRecord">The extra metadata about the mod from SMAPI's internal data (if any).</param>
 private void SetupMetadataForValidation(Mock <IModMetadata> mod, ModDataRecordVersionedFields modRecord = null)
 {
     mod.Setup(p => p.Status).Returns(ModMetadataStatus.Found);
     mod.Setup(p => p.DataRecord).Returns(() => null);
     mod.Setup(p => p.Manifest).Returns(this.GetManifest());
     mod.Setup(p => p.DirectoryPath).Returns(Path.GetTempPath());
     mod.Setup(p => p.DataRecord).Returns(modRecord);
 }
コード例 #5
0
ファイル: ModResolverTests.cs プロジェクト: kurumushi/SMAPI
 /// <summary>Set up a mock mod metadata for <see cref="ModResolver.ValidateManifests"/>.</summary>
 /// <param name="mod">The mock mod metadata.</param>
 /// <param name="modRecord">The extra metadata about the mod from SMAPI's internal data (if any).</param>
 private void SetupMetadataForValidation(Mock <IModMetadata> mod, ModDataRecordVersionedFields modRecord = null)
 {
     mod.Setup(p => p.Status).Returns(ModMetadataStatus.Found);
     mod.Setup(p => p.DataRecord).Returns(() => null);
     mod.Setup(p => p.Manifest).Returns(this.GetManifest());
     mod.Setup(p => p.DirectoryPath).Returns(Path.GetTempPath());
     mod.Setup(p => p.DataRecord).Returns(modRecord);
     mod.Setup(p => p.GetUpdateKeys(It.IsAny <bool>())).Returns(Enumerable.Empty <UpdateKey>());
 }
コード例 #6
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));
            }
        }
コード例 #7
0
        public bool GetUpdateStatuses(out IList <ModStatus> statuses)
        {
            statuses = new List <ModStatus>();


            object registry = this.helper.ModRegistry.GetType()
                              .GetField("Registry", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this.helper.ModRegistry);

            bool addedNonSkippedStatus = false;

            foreach (object modMetaData in (IEnumerable <object>)registry.GetType().GetField("Mods", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(registry))
            {
                ModEntryModel result   = GetInstanceProperty <ModEntryModel>(modMetaData, "UpdateCheckData");
                IManifest     manifest = GetInstanceProperty <IManifest>(modMetaData, "Manifest");

                if (result == null)
                {
                    statuses.Add(new ModStatus(UpdateStatus.Skipped, manifest, "", null, "SMAPI didn't check for an update"));
                    continue;
                }

                if (!(bool)modMetaData.GetType().GetMethod("HasValidUpdateKeys").Invoke(modMetaData, null))
                {
                    statuses.Add(new ModStatus(UpdateStatus.Skipped, manifest, "", null, "Mod has no update keys"));
                    continue;
                }

                ModDataRecordVersionedFields dataRecord =
                    GetInstanceProperty <ModDataRecordVersionedFields>(modMetaData, "DataRecord");

                //This section largely taken from https://github.com/Pathoschild/SMAPI/blob/924c3a5d3fe6bfad483834112883156bdf202b57/src/SMAPI/Framework/SCore.cs#L618-L630
                bool             useBetaInfo       = result.HasBetaInfo && Constants.ApiVersion.IsPrerelease();
                ISemanticVersion localVersion      = dataRecord?.GetLocalVersionForUpdateChecks(manifest.Version) ?? manifest.Version;
                ISemanticVersion latestVersion     = dataRecord?.GetRemoteVersionForUpdateChecks(result.Main?.Version) ?? result.Main?.Version;
                ISemanticVersion optionalVersion   = dataRecord?.GetRemoteVersionForUpdateChecks(result.Optional?.Version) ?? result.Optional?.Version;
                ISemanticVersion unofficialVersion = useBetaInfo ? result.UnofficialForBeta?.Version : result.Unofficial?.Version;

                if (this.IsValidUpdate(localVersion, latestVersion, useBetaChannel: true))
                {
                    statuses.Add(new ModStatus(UpdateStatus.OutOfDate, manifest, result.Main?.Url, latestVersion.ToString()));
                }
                else if (this.IsValidUpdate(localVersion, optionalVersion, useBetaChannel: localVersion.IsPrerelease()))
                {
                    statuses.Add(new ModStatus(UpdateStatus.OutOfDate, manifest, result.Optional?.Url, optionalVersion.ToString()));
                }
                else if (this.IsValidUpdate(localVersion, unofficialVersion, useBetaChannel: GetEnumName(modMetaData, "Status") == "Failed"))
                {
                    statuses.Add(new ModStatus(UpdateStatus.OutOfDate, manifest, useBetaInfo ? result.UnofficialForBeta?.Url : result.Unofficial?.Url, unofficialVersion.ToString()));
                }
                else
                {
                    string       updateURL    = null;
                    UpdateStatus updateStatus = UpdateStatus.UpToDate;
                    if (localVersion.Equals(latestVersion))
                    {
                        updateURL = result.Main?.Url;
                    }
                    else if (localVersion.Equals(optionalVersion))
                    {
                        updateURL = result.Optional?.Url;
                    }
                    else if (localVersion.Equals(unofficialVersion))
                    {
                        updateURL = useBetaInfo ? result.UnofficialForBeta?.Url : result.Unofficial?.Url;
                    }
                    else if (latestVersion != null && this.IsValidUpdate(latestVersion, localVersion, useBetaChannel: true))
                    {
                        updateURL    = result.Main?.Url;
                        updateStatus = UpdateStatus.VeryNew;
                    }
                    else if (optionalVersion != null && this.IsValidUpdate(optionalVersion, localVersion, useBetaChannel: localVersion.IsPrerelease()))
                    {
                        updateURL    = result.Optional?.Url;
                        updateStatus = UpdateStatus.VeryNew;
                    }
                    else if (unofficialVersion != null && this.IsValidUpdate(unofficialVersion, localVersion, useBetaChannel: GetEnumName(modMetaData, "Status") == "Failed"))
                    {
                        updateURL    = useBetaInfo ? result.UnofficialForBeta?.Url : result.Unofficial?.Url;
                        updateStatus = UpdateStatus.VeryNew;
                    }

                    if (updateURL != null)
                    {
                        statuses.Add(new ModStatus(updateStatus, manifest, updateURL));
                    }
                    else if (result.Errors != null && result.Errors.Any())
                    {
                        statuses.Add(new ModStatus(UpdateStatus.Error, manifest, "", "", result.Errors[0]));
                    }
                    else
                    {
                        statuses.Add(new ModStatus(UpdateStatus.Error, manifest, "", "", "Unknown Error"));
                    }
                }

                addedNonSkippedStatus = true;
            }

            return(addedNonSkippedStatus);
        }
コード例 #8
0
 /*********
 ** Public methods
 *********/
 /// <summary>Construct an instance.</summary>
 /// <param name="displayName">The mod's display name.</param>
 /// <param name="directoryPath">The mod's full directory path within the <paramref name="rootPath"/>.</param>
 /// <param name="rootPath">The root path containing mods.</param>
 /// <param name="manifest">The mod manifest.</param>
 /// <param name="dataRecord">Metadata about the mod from SMAPI's internal data (if any).</param>
 /// <param name="isIgnored">Whether the mod folder should be ignored. This should be <c>true</c> if it was found within a folder whose name starts with a dot.</param>
 public ModMetadata(string displayName, string directoryPath, string rootPath, IManifest manifest, ModDataRecordVersionedFields dataRecord, bool isIgnored)
 {
     this.DisplayName           = displayName;
     this.DirectoryPath         = directoryPath;
     this.RootPath              = rootPath;
     this.RelativeDirectoryPath = PathUtilities.GetRelativePath(this.RootPath, this.DirectoryPath);
     this.Manifest              = manifest;
     this.DataRecord            = dataRecord;
     this.IsIgnored             = isIgnored;
 }
コード例 #9
0
ファイル: ModMetadata.cs プロジェクト: Elatesan/SMAPI
 /*********
 ** Public methods
 *********/
 /// <summary>Construct an instance.</summary>
 /// <param name="displayName">The mod's display name.</param>
 /// <param name="directoryPath">The mod's full directory path.</param>
 /// <param name="manifest">The mod manifest.</param>
 /// <param name="dataRecord">Metadata about the mod from SMAPI's internal data (if any).</param>
 public ModMetadata(string displayName, string directoryPath, IManifest manifest, ModDataRecordVersionedFields dataRecord)
 {
     this.DisplayName   = displayName;
     this.DirectoryPath = directoryPath;
     this.Manifest      = manifest;
     this.DataRecord    = dataRecord;
 }
コード例 #10
0
        /*********
        ** Public methods
        *********/
        /// <summary>Construct an instance.</summary>
        /// <param name="displayName">The mod's display name.</param>
        /// <param name="directoryPath">The mod's full directory path within the <paramref name="rootPath"/>.</param>
        /// <param name="rootPath">The root path containing mods.</param>
        /// <param name="manifest">The mod manifest.</param>
        /// <param name="dataRecord">Metadata about the mod from SMAPI's internal data (if any).</param>
        /// <param name="isIgnored">Whether the mod folder should be ignored. This should be <c>true</c> if it was found within a folder whose name starts with a dot.</param>
        public ModMetadata(string displayName, string directoryPath, string rootPath, IManifest manifest, ModDataRecordVersionedFields dataRecord, bool isIgnored)
        {
            this.DisplayName           = displayName;
            this.DirectoryPath         = directoryPath;
            this.RootPath              = rootPath;
            this.RelativeDirectoryPath = PathUtilities.GetRelativePath(this.RootPath, this.DirectoryPath);
            this.Manifest              = manifest;
            this.DataRecord            = dataRecord;
            this.IsIgnored             = isIgnored;

            this.Dependencies = new Lazy <IDictionary <string, bool> >(this.ExtractDependencies);
        }