diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-10-27 22:08:00 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-10-27 22:08:00 -0400 |
commit | 88ea1eae13f3c5e3bfcedfb2ac9139c6dc829bac (patch) | |
tree | 5ce2a537117a883d661434a75c62efe6c07b75d1 | |
parent | 8231d05a33d8783093dd993cbe004239039fe8e8 (diff) | |
download | SMAPI-88ea1eae13f3c5e3bfcedfb2ac9139c6dc829bac.tar.gz SMAPI-88ea1eae13f3c5e3bfcedfb2ac9139c6dc829bac.tar.bz2 SMAPI-88ea1eae13f3c5e3bfcedfb2ac9139c6dc829bac.zip |
add support for ignored mod folders
-rw-r--r-- | docs/release-notes.md | 4 | ||||
-rw-r--r-- | src/SMAPI/Framework/IModMetadata.cs | 3 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/ModMetadata.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/ModResolver.cs | 4 | ||||
-rw-r--r-- | src/SMAPI/Framework/SCore.cs | 9 | ||||
-rw-r--r-- | src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModFolder.cs | 7 | ||||
-rw-r--r-- | src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModScanner.cs | 6 |
7 files changed, 31 insertions, 9 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md index 22c483c4..acbaef99 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,9 +3,11 @@ * For players: * Update checks now work even for mods without update keys in most cases. * Reorganised SMAPI files: - * You can now group mods into subfolders to organise them. * Most SMAPI files are now tucked into a `smapi-internal` subfolder. * Save backups are now in a `save-backups` subfolder, so they're easier to access. Note that previous backups will be deleted when you update. + * Added support for organising mods: + * You can now group mods into subfolders to organise them. + * You can now mark a mod folder ignored by starting the name with a dot (like `.disabled mods`). * Improved various error messages to be more clear and intuitive. * SMAPI now prevents a crash caused by mods adding dialogue the game can't parse. * When you have an older game version, SMAPI now recommends a compatible SMAPI version in its error. diff --git a/src/SMAPI/Framework/IModMetadata.cs b/src/SMAPI/Framework/IModMetadata.cs index a62c9950..bda9429f 100644 --- a/src/SMAPI/Framework/IModMetadata.cs +++ b/src/SMAPI/Framework/IModMetadata.cs @@ -33,6 +33,9 @@ namespace StardewModdingAPI.Framework /// <summary>The reason the metadata is invalid, if any.</summary> string Error { get; } + /// <summary>Whether the mod folder should be ignored. This is <c>true</c> if it was found within a folder whose name starts with a dot.</summary> + bool IsIgnored { get; } + /// <summary>The mod instance (if loaded and <see cref="IModInfo.IsContentPack"/> is false).</summary> IMod Mod { get; } diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index 0a5f5d3f..04aa679b 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -37,6 +37,9 @@ namespace StardewModdingAPI.Framework.ModLoading /// <summary>The reason the metadata is invalid, if any.</summary> public string Error { get; private set; } + /// <summary>Whether the mod folder should be ignored. This is <c>true</c> if it was found within a folder whose name starts with a dot.</summary> + public bool IsIgnored { get; } + /// <summary>The mod instance (if loaded and <see cref="IsContentPack"/> is false).</summary> public IMod Mod { get; private set; } @@ -65,13 +68,15 @@ namespace StardewModdingAPI.Framework.ModLoading /// <param name="relativeDirectoryPath">The <paramref name="directoryPath"/> relative to the game's Mods folder.</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, string relativeDirectoryPath, IManifest manifest, ModDataRecordVersionedFields dataRecord) + /// <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 relativeDirectoryPath, IManifest manifest, ModDataRecordVersionedFields dataRecord, bool isIgnored) { this.DisplayName = displayName; this.DirectoryPath = directoryPath; this.RelativeDirectoryPath = relativeDirectoryPath; this.Manifest = manifest; this.DataRecord = dataRecord; + this.IsIgnored = isIgnored; } /// <summary>Set the mod status.</summary> diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index 26ec82d7..9992cc78 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -38,11 +38,11 @@ namespace StardewModdingAPI.Framework.ModLoading } // build metadata - ModMetadataStatus status = folder.ManifestParseError == null + 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).SetStatus(status, folder.ManifestParseError); + yield return new ModMetadata(folder.DisplayName, folder.Directory.FullName, relativePath, manifest, dataRecord, isIgnored: !folder.ShouldBeLoaded).SetStatus(status, folder.ManifestParseError ?? "disabled by dot convention"); } } diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 6c897382..a17af91e 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -373,12 +373,15 @@ namespace StardewModdingAPI.Framework // load manifests IModMetadata[] mods = resolver.ReadManifests(toolkit, this.ModsPath, modDatabase).ToArray(); - resolver.ValidateManifests(mods, Constants.ApiVersion, toolkit.GetUpdateUrl); - // process dependencies - mods = resolver.ProcessDependencies(mods, modDatabase).ToArray(); + // filter out ignored mods + foreach (IModMetadata mod in mods.Where(p => p.IsIgnored)) + this.Monitor.Log($" Skipped {mod.RelativeDirectoryPath} (folder name starts with a dot).", LogLevel.Trace); + mods = mods.Where(p => !p.IsIgnored).ToArray(); // load mods + resolver.ValidateManifests(mods, Constants.ApiVersion, toolkit.GetUpdateUrl); + mods = resolver.ProcessDependencies(mods, modDatabase).ToArray(); this.LoadMods(mods, this.Toolkit.JsonHelper, this.ContentCore, modDatabase); // write metadata file diff --git a/src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModFolder.cs b/src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModFolder.cs index d2fea9e2..bb467b36 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModFolder.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModFolder.cs @@ -24,6 +24,9 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning /// <summary>The error which occurred parsing the manifest, if any.</summary> public string ManifestParseError { get; } + /// <summary>Whether the mod should be loaded by default. This is <c>false</c> if it was found within a folder whose name starts with a dot.</summary> + public bool ShouldBeLoaded { get; } + /********* ** Public methods @@ -33,12 +36,14 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning /// <param name="directory">The folder containing the mod's manifest.json.</param> /// <param name="manifest">The mod manifest.</param> /// <param name="manifestParseError">The error which occurred parsing the manifest, if any.</param> - public ModFolder(DirectoryInfo root, DirectoryInfo directory, Manifest manifest, string manifestParseError = null) + /// <param name="shouldBeLoaded">Whether the mod should be loaded by default. This should be <c>false</c> if it was found within a folder whose name starts with a dot.</param> + public ModFolder(DirectoryInfo root, DirectoryInfo directory, Manifest manifest, string manifestParseError = null, bool shouldBeLoaded = true) { // save info this.Directory = directory; this.Manifest = manifest; this.ManifestParseError = manifestParseError; + this.ShouldBeLoaded = shouldBeLoaded; // set display name this.DisplayName = manifest?.Name; diff --git a/src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModScanner.cs b/src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModScanner.cs index 2c23a3ce..106c294f 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModScanner.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/ModScanning/ModScanner.cs @@ -102,8 +102,12 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning /// <param name="folder">The folder to search for mods.</param> public IEnumerable<ModFolder> GetModFolders(DirectoryInfo root, DirectoryInfo folder) { + // skip + if (folder.FullName != root.FullName && folder.Name.StartsWith(".")) + yield return new ModFolder(root, folder, null, "ignored folder because its name starts with a dot.", shouldBeLoaded: false); + // recurse into subfolders - if (this.IsModSearchFolder(root, folder)) + else if (this.IsModSearchFolder(root, folder)) { foreach (DirectoryInfo subfolder in folder.EnumerateDirectories()) { |