From a2523696fd539621351c178f6ff57ade19dd3e34 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 1 Jun 2018 21:40:17 -0400 Subject: fix issue where a mod crashing in CanEdit/CanLoad could cause an abort-retry loop --- src/SMAPI/Framework/ContentCoordinator.cs | 59 ++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) (limited to 'src/SMAPI/Framework') diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index caa5b538..15d39a5c 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -11,7 +11,6 @@ using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Framework.Utilities; using StardewModdingAPI.Metadata; using StardewValley; -using xTile; namespace StardewModdingAPI.Framework { @@ -179,12 +178,36 @@ namespace StardewModdingAPI.Framework { // check loaders MethodInfo canLoadGeneric = canLoad.MakeGenericMethod(asset.DataType); - if (loaders.Any(loader => (bool)canLoadGeneric.Invoke(loader, new object[] { asset }))) - return true; + foreach (IAssetLoader loader in loaders) + { + try + { + if ((bool)canLoadGeneric.Invoke(loader, new object[] { asset })) + return true; + } + catch (Exception ex) + { + this.GetModFor(loader).LogAsMod($"Mod failed when checking whether it could load asset '{asset.AssetName}'. Error details:\n{ex.GetLogSummary()}", LogLevel.Error); + } + } // check editors MethodInfo canEditGeneric = canEdit.MakeGenericMethod(asset.DataType); - return editors.Any(editor => (bool)canEditGeneric.Invoke(editor, new object[] { asset })); + foreach (IAssetEditor editor in editors) + { + try + { + if ((bool)canEditGeneric.Invoke(editor, new object[] { asset })) + return true; + } + catch (Exception ex) + { + this.GetModFor(editor).LogAsMod($"Mod failed when checking whether it could edit asset '{asset.AssetName}'. Error details:\n{ex.GetLogSummary()}", LogLevel.Error); + } + } + + // asset not affected by a loader or editor + return false; }); } @@ -259,5 +282,33 @@ namespace StardewModdingAPI.Framework this.ContentManagers.Remove(contentManager); } + + /// Get the mod which registered an asset loader. + /// The asset loader. + /// The given loader couldn't be matched to a mod. + private IModMetadata GetModFor(IAssetLoader loader) + { + foreach (var pair in this.Loaders) + { + if (pair.Value.Contains(loader)) + return pair.Key; + } + + throw new KeyNotFoundException("This loader isn't associated with a known mod."); + } + + /// Get the mod which registered an asset editor. + /// The asset editor. + /// The given editor couldn't be matched to a mod. + private IModMetadata GetModFor(IAssetEditor editor) + { + foreach (var pair in this.Editors) + { + if (pair.Value.Contains(editor)) + return pair.Key; + } + + throw new KeyNotFoundException("This editor isn't associated with a known mod."); + } } } -- cgit