summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI/Framework/ModRegistry.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/StardewModdingAPI/Framework/ModRegistry.cs')
-rw-r--r--src/StardewModdingAPI/Framework/ModRegistry.cs117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/StardewModdingAPI/Framework/ModRegistry.cs b/src/StardewModdingAPI/Framework/ModRegistry.cs
new file mode 100644
index 00000000..8f30d813
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/ModRegistry.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+
+namespace StardewModdingAPI.Framework
+{
+ /// <summary>Tracks the installed mods.</summary>
+ internal class ModRegistry
+ {
+ /*********
+ ** Properties
+ *********/
+ /// <summary>The registered mod data.</summary>
+ private readonly List<IModMetadata> Mods = new List<IModMetadata>();
+
+ /// <summary>The friendly mod names treated as deprecation warning sources (assembly full name => mod name).</summary>
+ private readonly IDictionary<string, string> ModNamesByAssembly = new Dictionary<string, string>();
+
+
+ /*********
+ ** Public methods
+ *********/
+ /****
+ ** Basic metadata
+ ****/
+ /// <summary>Get metadata for all loaded mods.</summary>
+ public IEnumerable<IManifest> GetAll()
+ {
+ return this.Mods.Select(p => p.Manifest);
+ }
+
+ /// <summary>Get metadata for a loaded mod.</summary>
+ /// <param name="uniqueID">The mod's unique ID.</param>
+ /// <returns>Returns the matching mod's metadata, or <c>null</c> if not found.</returns>
+ public IManifest Get(string uniqueID)
+ {
+ // normalise search ID
+ if (string.IsNullOrWhiteSpace(uniqueID))
+ return null;
+ uniqueID = uniqueID.Trim();
+
+ // find match
+ return this.GetAll().FirstOrDefault(p =>
+#if SMAPI_1_x
+ p.UniqueID != null &&
+#endif
+ p.UniqueID.Trim().Equals(uniqueID, StringComparison.InvariantCultureIgnoreCase));
+ }
+
+ /// <summary>Get whether a mod has been loaded.</summary>
+ /// <param name="uniqueID">The mod's unique ID.</param>
+ public bool IsLoaded(string uniqueID)
+ {
+ return this.Get(uniqueID) != null;
+ }
+
+ /****
+ ** Mod data
+ ****/
+ /// <summary>Register a mod as a possible source of deprecation warnings.</summary>
+ /// <param name="metadata">The mod metadata.</param>
+ public void Add(IModMetadata metadata)
+ {
+ this.Mods.Add(metadata);
+ this.ModNamesByAssembly[metadata.Mod.GetType().Assembly.FullName] = metadata.DisplayName;
+ }
+
+ /// <summary>Get all enabled mods.</summary>
+ public IEnumerable<IModMetadata> GetMods()
+ {
+ return (from mod in this.Mods select mod);
+ }
+
+ /// <summary>Get the friendly mod name which defines a type.</summary>
+ /// <param name="type">The type to check.</param>
+ /// <returns>Returns the mod name, or <c>null</c> if the type isn't part of a known mod.</returns>
+ public string GetModFrom(Type type)
+ {
+ // null
+ if (type == null)
+ return null;
+
+ // known type
+ string assemblyName = type.Assembly.FullName;
+ if (this.ModNamesByAssembly.ContainsKey(assemblyName))
+ return this.ModNamesByAssembly[assemblyName];
+
+ // not found
+ return null;
+ }
+
+ /// <summary>Get the friendly name for the closest assembly registered as a source of deprecation warnings.</summary>
+ /// <returns>Returns the source name, or <c>null</c> if no registered assemblies were found.</returns>
+ public string GetModFromStack()
+ {
+ // get stack frames
+ StackTrace stack = new StackTrace();
+ StackFrame[] frames = stack.GetFrames();
+ if (frames == null)
+ return null;
+
+ // search stack for a source assembly
+ foreach (StackFrame frame in frames)
+ {
+ MethodBase method = frame.GetMethod();
+ string name = this.GetModFrom(method.ReflectedType);
+ if (name != null)
+ return name;
+ }
+
+ // no known assembly found
+ return null;
+ }
+ }
+}