list broken dependencies first in 'skipped mods' list
This commit is contained in:
parent
4c471ea215
commit
d932a11f51
|
@ -6,6 +6,7 @@
|
|||
* For players:
|
||||
* Added friendly log message for save file-not-found errors.
|
||||
* Updated for the 'Force Off' gamepad mode added in Stardew Valley 1.4.1.
|
||||
* The 'skipped mods' list now shows broken dependencies first, so it's easier to see which ones to fix first.
|
||||
* Fixed compatibility with Linux Mint 18 (thanks to techge!) and Arch Linux.
|
||||
* Fixed compatibility with Linux systems which have libhybris-utils installed.
|
||||
* Fixes for the bundled Console Commands mod:
|
||||
|
|
|
@ -105,6 +105,10 @@ namespace StardewModdingAPI.Framework
|
|||
/// <param name="validOnly">Only return valid update keys.</param>
|
||||
IEnumerable<UpdateKey> GetUpdateKeys(bool validOnly = true);
|
||||
|
||||
/// <summary>Get the mod IDs that must be installed to load this mod.</summary>
|
||||
/// <param name="includeOptional">Whether to include optional dependencies.</param>
|
||||
IEnumerable<string> GetRequiredModIds(bool includeOptional = false);
|
||||
|
||||
/// <summary>Whether the mod has at least one valid update key set.</summary>
|
||||
bool HasValidUpdateKeys();
|
||||
|
||||
|
|
|
@ -188,6 +188,27 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Get the mod IDs that must be installed to load this mod.</summary>
|
||||
/// <param name="includeOptional">Whether to include optional dependencies.</param>
|
||||
public IEnumerable<string> GetRequiredModIds(bool includeOptional = false)
|
||||
{
|
||||
HashSet<string> required = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
// yield dependencies
|
||||
if (this.Manifest?.Dependencies != null)
|
||||
{
|
||||
foreach (var entry in this.Manifest?.Dependencies)
|
||||
{
|
||||
if ((entry.IsRequired || includeOptional) && required.Add(entry.UniqueID))
|
||||
yield return entry.UniqueID;
|
||||
}
|
||||
}
|
||||
|
||||
// yield content pack parent
|
||||
if (this.Manifest?.ContentPackFor?.UniqueID != null && required.Add(this.Manifest.ContentPackFor.UniqueID))
|
||||
yield return this.Manifest.ContentPackFor.UniqueID;
|
||||
}
|
||||
|
||||
/// <summary>Whether the mod has at least one valid update key set.</summary>
|
||||
public bool HasValidUpdateKeys()
|
||||
{
|
||||
|
|
|
@ -1046,26 +1046,48 @@ namespace StardewModdingAPI.Framework
|
|||
// log skipped mods
|
||||
if (skippedMods.Any())
|
||||
{
|
||||
// get logging logic
|
||||
HashSet<string> logged = new HashSet<string>();
|
||||
void LogSkippedMod(IModMetadata mod, string errorReason, string errorDetails)
|
||||
{
|
||||
string message = $" - {mod.DisplayName}{(mod.Manifest?.Version != null ? " " + mod.Manifest.Version.ToString() : "")} because {errorReason}";
|
||||
|
||||
if (logged.Add($"{message}|{errorDetails}"))
|
||||
{
|
||||
this.Monitor.Log(message, LogLevel.Error);
|
||||
if (errorDetails != null)
|
||||
this.Monitor.Log($" ({errorDetails})", LogLevel.Trace);
|
||||
}
|
||||
}
|
||||
|
||||
// find skipped dependencies
|
||||
KeyValuePair<IModMetadata, Tuple<string, string>>[] skippedDependencies;
|
||||
{
|
||||
HashSet<string> skippedDependencyIds = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
HashSet<string> skippedModIds = new HashSet<string>(from mod in skippedMods where mod.Key.HasID() select mod.Key.Manifest.UniqueID, StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (IModMetadata mod in skippedMods.Keys)
|
||||
{
|
||||
foreach (string requiredId in skippedModIds.Intersect(mod.GetRequiredModIds()))
|
||||
skippedDependencyIds.Add(requiredId);
|
||||
}
|
||||
skippedDependencies = skippedMods.Where(p => p.Key.HasID() && skippedDependencyIds.Contains(p.Key.Manifest.UniqueID)).ToArray();
|
||||
}
|
||||
|
||||
// log skipped mods
|
||||
this.Monitor.Log(" Skipped mods", LogLevel.Error);
|
||||
this.Monitor.Log(" " + "".PadRight(50, '-'), LogLevel.Error);
|
||||
this.Monitor.Log(" These mods could not be added to your game.", LogLevel.Error);
|
||||
this.Monitor.Newline();
|
||||
|
||||
HashSet<string> logged = new HashSet<string>();
|
||||
foreach (var pair in skippedMods.OrderBy(p => p.Key.DisplayName))
|
||||
if (skippedDependencies.Any())
|
||||
{
|
||||
IModMetadata mod = pair.Key;
|
||||
string errorReason = pair.Value.Item1;
|
||||
string errorDetails = pair.Value.Item2;
|
||||
string message = $" - {mod.DisplayName}{(mod.Manifest?.Version != null ? " " + mod.Manifest.Version.ToString() : "")} because {errorReason}";
|
||||
|
||||
if (!logged.Add($"{message}|{errorDetails}"))
|
||||
continue; // skip duplicate messages (e.g. if multiple copies of the mod are installed)
|
||||
|
||||
this.Monitor.Log(message, LogLevel.Error);
|
||||
if (errorDetails != null)
|
||||
this.Monitor.Log($" ({errorDetails})", LogLevel.Trace);
|
||||
foreach (var pair in skippedDependencies.OrderBy(p => p.Key.DisplayName))
|
||||
LogSkippedMod(pair.Key, pair.Value.Item1, pair.Value.Item2);
|
||||
this.Monitor.Newline();
|
||||
}
|
||||
|
||||
foreach (var pair in skippedMods.OrderBy(p => p.Key.DisplayName))
|
||||
LogSkippedMod(pair.Key, pair.Value.Item1, pair.Value.Item2);
|
||||
this.Monitor.Newline();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue