summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r--src/SMAPI/Framework/IModMetadata.cs10
-rw-r--r--src/SMAPI/Framework/ModLoading/ModMetadata.cs25
-rw-r--r--src/SMAPI/Framework/ModLoading/ModResolver.cs12
-rw-r--r--src/SMAPI/Framework/SCore.cs10
4 files changed, 41 insertions, 16 deletions
diff --git a/src/SMAPI/Framework/IModMetadata.cs b/src/SMAPI/Framework/IModMetadata.cs
index 32870c2a..6ee7df69 100644
--- a/src/SMAPI/Framework/IModMetadata.cs
+++ b/src/SMAPI/Framework/IModMetadata.cs
@@ -16,10 +16,13 @@ namespace StardewModdingAPI.Framework
/// <summary>The mod's display name.</summary>
string DisplayName { get; }
- /// <summary>The mod's full directory path.</summary>
+ /// <summary>The root path containing mods.</summary>
+ string RootPath { get; }
+
+ /// <summary>The mod's full directory path within the <see cref="RootPath"/>.</summary>
string DirectoryPath { get; }
- /// <summary>The <see cref="DirectoryPath"/> relative to the game's Mods folder.</summary>
+ /// <summary>The <see cref="DirectoryPath"/> relative to the <see cref="RootPath"/>.</summary>
string RelativeDirectoryPath { get; }
/// <summary>Metadata about the mod from SMAPI's internal data (if any).</summary>
@@ -108,5 +111,8 @@ namespace StardewModdingAPI.Framework
/// <summary>Get whether the mod has a given warning and it hasn't been suppressed in the <see cref="DataRecord"/>.</summary>
/// <param name="warning">The warning to check.</param>
bool HasUnsuppressWarning(ModWarning warning);
+
+ /// <summary>Get a relative path which includes the root folder name.</summary>
+ string GetRelativePathWithRoot();
}
}
diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs
index 39f2f482..7f788d17 100644
--- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs
+++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using StardewModdingAPI.Framework.ModHelpers;
using StardewModdingAPI.Toolkit.Framework.Clients.WebApi;
using StardewModdingAPI.Toolkit.Framework.ModData;
using StardewModdingAPI.Toolkit.Framework.UpdateData;
+using StardewModdingAPI.Toolkit.Utilities;
namespace StardewModdingAPI.Framework.ModLoading
{
@@ -17,10 +19,13 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>The mod's display name.</summary>
public string DisplayName { get; }
- /// <summary>The mod's full directory path.</summary>
+ /// <summary>The root path containing mods.</summary>
+ public string RootPath { get; }
+
+ /// <summary>The mod's full directory path within the <see cref="RootPath"/>.</summary>
public string DirectoryPath { get; }
- /// <summary>The <see cref="IModMetadata.DirectoryPath"/> relative to the game's Mods folder.</summary>
+ /// <summary>The <see cref="DirectoryPath"/> relative to the <see cref="RootPath"/>.</summary>
public string RelativeDirectoryPath { get; }
/// <summary>The mod manifest.</summary>
@@ -68,16 +73,17 @@ namespace StardewModdingAPI.Framework.ModLoading
*********/
/// <summary>Construct an instance.</summary>
/// <param name="displayName">The mod's display name.</param>
- /// <param name="directoryPath">The mod's full directory path.</param>
- /// <param name="relativeDirectoryPath">The <paramref name="directoryPath"/> relative to the game's Mods folder.</param>
+ /// <param name="directoryPath">The mod's full directory path within the <paramref name="rootPath"/>.</param>
+ /// <param name="rootPath">The root path containing mods.</param>
/// <param name="manifest">The mod manifest.</param>
/// <param name="dataRecord">Metadata about the mod from SMAPI's internal data (if any).</param>
/// <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)
+ public ModMetadata(string displayName, string directoryPath, string rootPath, IManifest manifest, ModDataRecordVersionedFields dataRecord, bool isIgnored)
{
this.DisplayName = displayName;
this.DirectoryPath = directoryPath;
- this.RelativeDirectoryPath = relativeDirectoryPath;
+ this.RootPath = rootPath;
+ this.RelativeDirectoryPath = PathUtilities.GetRelativePath(this.RootPath, this.DirectoryPath);
this.Manifest = manifest;
this.DataRecord = dataRecord;
this.IsIgnored = isIgnored;
@@ -196,5 +202,12 @@ namespace StardewModdingAPI.Framework.ModLoading
this.Warnings.HasFlag(warning)
&& (this.DataRecord?.DataRecord == null || !this.DataRecord.DataRecord.SuppressWarnings.HasFlag(warning));
}
+
+ /// <summary>Get a relative path which includes the root folder name.</summary>
+ public string GetRelativePathWithRoot()
+ {
+ string rootFolderName = Path.GetFileName(this.RootPath) ?? "";
+ return Path.Combine(rootFolderName, this.RelativeDirectoryPath);
+ }
}
}
diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs
index b6bdb357..20941a5f 100644
--- a/src/SMAPI/Framework/ModLoading/ModResolver.cs
+++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs
@@ -42,9 +42,8 @@ namespace StardewModdingAPI.Framework.ModLoading
ModMetadataStatus status = folder.ManifestParseError == ModParseError.None || shouldIgnore
? ModMetadataStatus.Found
: ModMetadataStatus.Failed;
- string relativePath = PathUtilities.GetRelativePath(rootPath, folder.Directory.FullName);
- yield return new ModMetadata(folder.DisplayName, folder.Directory.FullName, relativePath, manifest, dataRecord, isIgnored: shouldIgnore)
+ yield return new ModMetadata(folder.DisplayName, folder.Directory.FullName, rootPath, manifest, dataRecord, isIgnored: shouldIgnore)
.SetStatus(status, shouldIgnore ? "disabled by dot convention" : folder.ManifestParseErrorText);
}
}
@@ -199,7 +198,14 @@ namespace StardewModdingAPI.Framework.ModLoading
{
if (mod.Status == ModMetadataStatus.Failed)
continue; // don't replace metadata error
- mod.SetStatus(ModMetadataStatus.Failed, $"you have multiple copies of this mod installed ({string.Join(", ", group.Select(p => p.RelativeDirectoryPath).OrderBy(p => p))}).");
+
+ string folderList = string.Join(", ",
+ from entry in @group
+ let relativePath = entry.GetRelativePathWithRoot()
+ orderby relativePath
+ select $"{relativePath} ({entry.Manifest.Version})"
+ );
+ mod.SetStatus(ModMetadataStatus.Failed, $"you have multiple copies of this mod installed. Found in folders: {folderList}.");
}
}
}
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index 60deed70..0aae3b84 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -400,7 +400,7 @@ namespace StardewModdingAPI.Framework
// 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);
+ this.Monitor.Log($" Skipped {mod.GetRelativePathWithRoot()} (folder name starts with a dot).", LogLevel.Trace);
mods = mods.Where(p => !p.IsIgnored).ToArray();
// load mods
@@ -902,13 +902,13 @@ namespace StardewModdingAPI.Framework
// log entry
{
- string relativePath = PathUtilities.GetRelativePath(this.ModsPath, mod.DirectoryPath);
+ string relativePath = mod.GetRelativePathWithRoot();
if (mod.IsContentPack)
- this.Monitor.Log($" {mod.DisplayName} ({relativePath}) [content pack]...", LogLevel.Trace);
+ this.Monitor.Log($" {mod.DisplayName} (from {relativePath}) [content pack]...", LogLevel.Trace);
else if (mod.Manifest?.EntryDll != null)
- this.Monitor.Log($" {mod.DisplayName} ({relativePath}{Path.DirectorySeparatorChar}{mod.Manifest.EntryDll})...", LogLevel.Trace); // don't use Path.Combine here, since EntryDLL might not be valid
+ this.Monitor.Log($" {mod.DisplayName} (from {relativePath}{Path.DirectorySeparatorChar}{mod.Manifest.EntryDll})...", LogLevel.Trace); // don't use Path.Combine here, since EntryDLL might not be valid
else
- this.Monitor.Log($" {mod.DisplayName} ({relativePath})...", LogLevel.Trace);
+ this.Monitor.Log($" {mod.DisplayName} (from {relativePath})...", LogLevel.Trace);
}
// add warning for missing update key