summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r--src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs56
-rw-r--r--src/SMAPI/Framework/SCore.cs5
2 files changed, 30 insertions, 31 deletions
diff --git a/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs b/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs
index 9ad3e3ae..8cc73481 100644
--- a/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs
@@ -68,49 +68,43 @@ namespace StardewModdingAPI.Framework.ModHelpers
return null;
}
- // get our cached API if one is available
+ // get the target mod
IModMetadata? mod = this.Registry.Get(uniqueID);
if (mod == null)
return null;
- if (this.AccessedModApis.ContainsKey(mod.Manifest.UniqueID))
+ // fetch API
+ if (!this.AccessedModApis.TryGetValue(mod.Manifest.UniqueID, out object? api))
{
- return this.AccessedModApis[mod.Manifest.UniqueID];
- }
-
- object? api;
+ // if the target has a global API, this is mutually exclusive with per-mod APIs
+ if (mod.Api != null)
+ api = mod.Api;
- // safely request a specific API instance
- try
- {
- api = mod.Mod?.GetApi(this.Mod.Manifest);
- if (api != null && !api.GetType().IsPublic)
+ // else try to get a per-mod API
+ else
{
- api = null;
- this.Monitor.Log($"{mod.DisplayName} provided a specific API instance with a non-public type. This isn't currently supported, so the specific API won't be available to the requesting mod.", LogLevel.Warn);
+ try
+ {
+ api = mod.Mod?.GetApi(this.Mod.Manifest);
+ if (api != null && !api.GetType().IsPublic)
+ {
+ api = null;
+ this.Monitor.Log($"{mod.DisplayName} provides a per-mod API instance with a non-public type. This isn't currently supported, so the API won't be available to other mods.", LogLevel.Warn);
+ }
+ }
+ catch (Exception ex)
+ {
+ this.Monitor.Log($"Failed loading the per-mod API instance from {mod.DisplayName}. Integrations with other mods may not work. Error: {ex.GetLogSummary()}", LogLevel.Error);
+ api = null;
+ }
}
+ // cache & log API access
+ this.AccessedModApis[mod.Manifest.UniqueID] = api;
if (api != null)
- this.Monitor.Log($"Accessed specific mod-provided API ({api.GetType().FullName}) for {mod.DisplayName}.");
- }
- catch (Exception ex)
- {
- this.Monitor.Log($"Failed loading specific mod-provided API for {mod.DisplayName}. Integrations with other mods may not work. Error: {ex.GetLogSummary()}", LogLevel.Error);
- api = null;
- }
-
- // fall back to the generic API instance
- if (api == null)
- {
- api = mod.Api;
- if (api != null)
- {
- this.Monitor.Log($"Accessed mod-provided API for {mod.DisplayName}.");
- }
+ this.Monitor.Log($"Accessed mod-provided API ({api.GetType().FullName}) for {mod.DisplayName}.");
}
- // cache the API instance and return it
- this.AccessedModApis[mod.Manifest.UniqueID] = api;
return api;
}
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index 16ff2537..4ba0dd9c 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -1779,6 +1779,11 @@ namespace StardewModdingAPI.Framework
{
this.Monitor.Log($"Failed loading mod-provided API for {metadata.DisplayName}. Integrations with other mods may not work. Error: {ex.GetLogSummary()}", LogLevel.Error);
}
+
+ // validate mod doesn't implement both GetApi() and GetApi(mod)
+ if (metadata.Api != null && metadata.Mod!.GetType().GetMethod(nameof(Mod.GetApi), new Type[] { typeof(IManifest) })!.DeclaringType != typeof(Mod))
+ metadata.LogAsMod($"Mod implements both {nameof(Mod.GetApi)}() and {nameof(Mod.GetApi)}({nameof(IManifest)}), which isn't allowed. The latter will be ignored.", LogLevel.Error);
+
Context.HeuristicModsRunningCode.TryPop(out _);
}