summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2016-12-27 13:52:32 -0500
committerJesse Plamondon-Willard <github@jplamondonw.com>2016-12-27 13:52:32 -0500
commitb9dd6eb742e4f0c42ed887abd0f17f113f250056 (patch)
tree352a208a25780285419b0bae73148a00a98356ff
parentc24294c3dd73db3754d10ff8fe5bd51338555638 (diff)
parentb75d86e7cc19f9bc961abb475f22e8f2b059533c (diff)
downloadSMAPI-b9dd6eb742e4f0c42ed887abd0f17f113f250056.tar.gz
SMAPI-b9dd6eb742e4f0c42ed887abd0f17f113f250056.tar.bz2
SMAPI-b9dd6eb742e4f0c42ed887abd0f17f113f250056.zip
Merge branch 'develop' into stable
-rw-r--r--README.md10
-rw-r--r--release-notes.md84
-rw-r--r--src/GlobalAssemblyInfo.cs4
-rw-r--r--src/StardewModdingAPI.Installer/InteractiveInstaller.cs6
-rw-r--r--src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj6
-rw-r--r--src/StardewModdingAPI/Constants.cs14
-rw-r--r--src/StardewModdingAPI/Framework/AssemblyRewriting/CacheEntry.cs2
-rw-r--r--src/StardewModdingAPI/Framework/ModAssemblyLoader.cs4
-rw-r--r--src/StardewModdingAPI/Framework/ModRegistry.cs18
-rw-r--r--src/StardewModdingAPI/Framework/Models/GitRelease.cs (renamed from src/StardewModdingAPI/Framework/GitRelease.cs)2
-rw-r--r--src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs47
-rw-r--r--src/StardewModdingAPI/Framework/Models/UserSettings.cs15
-rw-r--r--src/StardewModdingAPI/Framework/Reflection/CacheEntry.cs30
-rw-r--r--src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs34
-rw-r--r--src/StardewModdingAPI/Framework/UpdateHelper.cs1
-rw-r--r--src/StardewModdingAPI/Framework/UserSettings.cs9
-rw-r--r--src/StardewModdingAPI/IManifest.cs27
-rw-r--r--src/StardewModdingAPI/IMod.cs26
-rw-r--r--src/StardewModdingAPI/ISemanticVersion.cs38
-rw-r--r--src/StardewModdingAPI/Inheritance/SGame.cs12
-rw-r--r--src/StardewModdingAPI/Inheritance/SObject.cs2
-rw-r--r--src/StardewModdingAPI/LogWriter.cs2
-rw-r--r--src/StardewModdingAPI/Manifest.cs60
-rw-r--r--src/StardewModdingAPI/Mod.cs17
-rw-r--r--src/StardewModdingAPI/Program.cs156
-rw-r--r--src/StardewModdingAPI/SemanticVersion.cs171
-rw-r--r--src/StardewModdingAPI/StardewModdingAPI-settings.json4
-rw-r--r--src/StardewModdingAPI/StardewModdingAPI.config.json4
-rw-r--r--src/StardewModdingAPI/StardewModdingAPI.csproj17
-rw-r--r--src/StardewModdingAPI/StardewModdingAPI.data.json41
-rw-r--r--src/StardewModdingAPI/Version.cs116
31 files changed, 755 insertions, 224 deletions
diff --git a/README.md b/README.md
index 39cfb25c..eb21f379 100644
--- a/README.md
+++ b/README.md
@@ -78,9 +78,10 @@ directory containing `src`).
Mono.Cecil.Rocks.dll
Newtonsoft.Json.dll
StardewModdingAPI
+ StardewModdingAPI.config.json
+ StardewModdingAPI.data.json
StardewModdingAPI.exe
StardewModdingAPI.exe.mdb
- StardewModdingAPI-settings.json
StardewModdingAPI.AssemblyRewriters.dll
System.Numerics.dll
System.Runtime.Caching.dll
@@ -90,10 +91,11 @@ directory containing `src`).
Mono.Cecil.dll
Mono.Cecil.Rocks.dll
Newtonsoft.Json.dll
+ StardewModdingAPI.config.json
+ StardewModdingAPI.data.json
StardewModdingAPI.exe
StardewModdingAPI.pdb
StardewModdingAPI.xml
- StardewModdingAPI-settings.json
StardewModdingAPI.AssemblyRewriters.dll
steam_appid.txt
install.exe
@@ -102,7 +104,7 @@ directory containing `src`).
4. Open a terminal in the `SMAPI-<version>` directory and run `chmod 755 Mono/StardewModdingAPI`.
5. Copy & paste the `SMAPI-<version>` directory as `SMAPI-<version>-for-developers`.
6. In the `SMAPI-<version>` directory, delete the following files:
- * `Mono/StardewModdingAPI-settings.json`
+ * `Mono/StardewModdingAPI.config.json`
+ * `Windows/StardewModdingAPI.config.json`
* `Windows/StardewModdingAPI.xml`
- * `Windows/StardewModdingAPI-settings.json`
7. Compress the two folders into `SMAPI-<version>.zip` and `SMAPI-<version>-for-developers.zip`. \ No newline at end of file
diff --git a/release-notes.md b/release-notes.md
index eb2d619e..a11d9ea8 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -1,7 +1,21 @@
# Release notes
+## 1.5
+See [log](https://github.com/Pathoschild/SMAPI/compare/1.4...1.5).
+
+For players:
+ * Added an option to disable update checks.
+ * SMAPI will now show a friendly error with update links when you try to use a known incompatible mod version.
+ * Fixed an error when a mod uses the new reflection API on a missing field or method.
+ * Fixed an issue where mods weren't notified of a menu change if it changed while SMAPI was still notifying mods of the previous change.
+
+For developers:
+ * Deprecated `Version` in favour of `SemanticVersion`.
+ _This new implementation is [semver 2.0](http://semver.org/)-compliant, introduces `NewerThan(version)` and `OlderThan(version)` convenience methods, adds support for parsing a version string into a `SemanticVersion`, and fixes various bugs with the former implementation. This also replaces `Manifest` with `IManifest`._
+ * Increased deprecation levels for `SObject`, `Extensions`, `LogWriter` (not `Log`), `SPlayer`, and `Mod.Entry(ModHelper)` (not `Mod.Entry(IModHelper)`).
+
## 1.4
-See [log](https://github.com/CLxS/SMAPI/compare/1.3...1.4).
+See [log](https://github.com/Pathoschild/SMAPI/compare/1.3...1.4).
For players:
* SMAPI will now prevent mods from crashing your game with menu errors.
@@ -20,14 +34,14 @@ For developers:
* Fixed an issue where you couldn't debug into an assembly because it was copied into the `.cache` directory. That will now only happen if necessary.
## 1.3
-See [log](https://github.com/CLxS/SMAPI/compare/1.2...1.3).
+See [log](https://github.com/Pathoschild/SMAPI/compare/1.2...1.3).
For players:
* You can now run most mods on any platform (e.g. run Windows mods on Linux/Mac).
* Fixed the normal uninstaller not removing files added by the 'SMAPI for developers' installer.
## 1.2
-See [log](https://github.com/CLxS/SMAPI/compare/1.1.1...1.2).
+See [log](https://github.com/Pathoschild/SMAPI/compare/1.1.1...1.2).
For players:
* Fixed compatibility with some older mods.
@@ -39,7 +53,7 @@ For developers:
* Improved logging to show `ReflectionTypeLoadException` details when it's caught by SMAPI.
## 1.1
-See [log](https://github.com/CLxS/SMAPI/compare/1.0...1.1.1).
+See [log](https://github.com/Pathoschild/SMAPI/compare/1.0...1.1.1).
For players:
* Fixed console exiting immediately when some exceptions occur.
@@ -60,7 +74,7 @@ For developers:
* Fixed deprecation warnings being repeated if the mod can't be identified.<sup>1.1.1</sup>
## 1.0
-See [log](https://github.com/CLxS/SMAPI/compare/0.40.1.1-3...1.0).
+See [log](https://github.com/Pathoschild/SMAPI/compare/0.40.1.1-3...1.0).
For players:
* Added support for Linux and Mac.
@@ -89,44 +103,44 @@ For SMAPI developers:
* Internal cleanup & refactoring.
## 0.x
-* 0.40.1.1 (2016-09-30, [log](https://github.com/CLxS/SMAPI/compare/0.40.0...0.40.1.1-3))
+* 0.40.1.1 (2016-09-30, [log](https://github.com/Pathoschild/SMAPI/compare/0.40.0...0.40.1.1-3))
* Added support for Stardew Valley 1.1.
-* 0.40.0 (2016-04-05, [log](https://github.com/CLxS/SMAPI/compare/0.39.7...0.40.0))
+* 0.40.0 (2016-04-05, [log](https://github.com/Pathoschild/SMAPI/compare/0.39.7...0.40.0))
* Fixed an error that ocurred during minigames.
-* 0.39.7 (2016-04-04, [log](https://github.com/CLxS/SMAPI/compare/0.39.6...0.39.7))
+* 0.39.7 (2016-04-04, [log](https://github.com/Pathoschild/SMAPI/compare/0.39.6...0.39.7))
* Added 'no check' graphics events that are triggered regardless of game's if checks.
-* 0.39.6 (2016-04-01, [log](https://github.com/CLxS/SMAPI/compare/0.39.5...0.39.6))
+* 0.39.6 (2016-04-01, [log](https://github.com/Pathoschild/SMAPI/compare/0.39.5...0.39.6))
* Added game & SMAPI versions to log.
* Fixed conflict in graphics tick events.
* Bug fixes.
-* 0.39.5 (2016-03-30, [log](https://github.com/CLxS/SMAPI/compare/0.39.4...0.39.5))
-* 0.39.4 (2016-03-29, [log](https://github.com/CLxS/SMAPI/compare/0.39.3...0.39.4))
-* 0.39.3 (2016-03-28, [log](https://github.com/CLxS/SMAPI/compare/0.39.2...0.39.3))
-* 0.39.2 (2016-03-23, [log](https://github.com/CLxS/SMAPI/compare/0.39.1...0.39.2))
-* 0.39.1 (2016-03-23, [log](https://github.com/CLxS/SMAPI/compare/0.38.8...0.39.1))
-* 0.38.8 (2016-03-23, [log](https://github.com/CLxS/SMAPI/compare/0.38.7...0.38.8))
-* 0.38.7 (2016-03-23, [log](https://github.com/CLxS/SMAPI/compare/0.38.6...0.38.7))
-* 0.38.6 (2016-03-22, [log](https://github.com/CLxS/SMAPI/compare/0.38.5...0.38.6))
-* 0.38.5 (2016-03-22, [log](https://github.com/CLxS/SMAPI/compare/0.38.4...0.38.5))
-* 0.38.4 (2016-03-21, [log](https://github.com/CLxS/SMAPI/compare/0.38.3...0.38.4))
-* 0.38.3 (2016-03-21, [log](https://github.com/CLxS/SMAPI/compare/0.38.2...0.38.3))
-* 0.38.2 (2016-03-21, [log](https://github.com/CLxS/SMAPI/compare/0.38.0...0.38.2))
-* 0.38.0 (2016-03-20, [log](https://github.com/CLxS/SMAPI/compare/0.38.1...0.38.0))
-* 0.38.1 (2016-03-20, [log](https://github.com/CLxS/SMAPI/compare/0.37.3...0.38.1))
-* 0.37.3 (2016-03-08, [log](https://github.com/CLxS/SMAPI/compare/0.37.2...0.37.3))
-* 0.37.2 (2016-03-07, [log](https://github.com/CLxS/SMAPI/compare/0.37.1...0.37.2))
-* 0.37.1 (2016-03-06, [log](https://github.com/CLxS/SMAPI/compare/0.36...0.37.1))
-* 0.36 (2016-03-04, [log](https://github.com/CLxS/SMAPI/compare/0.37...0.36))
-* 0.37 (2016-03-04, [log](https://github.com/CLxS/SMAPI/compare/0.35...0.37))
-* 0.35 (2016-03-02, [log](https://github.com/CLxS/SMAPI/compare/0.34...0.35))
-* 0.34 (2016-03-02, [log](https://github.com/CLxS/SMAPI/compare/0.33...0.34))
-* 0.33 (2016-03-02, [log](https://github.com/CLxS/SMAPI/compare/0.32...0.33))
-* 0.32 (2016-03-02, [log](https://github.com/CLxS/SMAPI/compare/0.31...0.32))
-* 0.31 (2016-03-02, [log](https://github.com/CLxS/SMAPI/compare/0.3...0.31))
-* 0.3 (2016-03-01, [log](https://github.com/CLxS/SMAPI/compare/Alpha0.2...0.3))
-* 0.2 (2016-02-29, [log](https://github.com/CLxS/SMAPI/compare/Alpha0.1...Alpha0.2)
+* 0.39.5 (2016-03-30, [log](https://github.com/Pathoschild/SMAPI/compare/0.39.4...0.39.5))
+* 0.39.4 (2016-03-29, [log](https://github.com/Pathoschild/SMAPI/compare/0.39.3...0.39.4))
+* 0.39.3 (2016-03-28, [log](https://github.com/Pathoschild/SMAPI/compare/0.39.2...0.39.3))
+* 0.39.2 (2016-03-23, [log](https://github.com/Pathoschild/SMAPI/compare/0.39.1...0.39.2))
+* 0.39.1 (2016-03-23, [log](https://github.com/Pathoschild/SMAPI/compare/0.38.8...0.39.1))
+* 0.38.8 (2016-03-23, [log](https://github.com/Pathoschild/SMAPI/compare/0.38.7...0.38.8))
+* 0.38.7 (2016-03-23, [log](https://github.com/Pathoschild/SMAPI/compare/0.38.6...0.38.7))
+* 0.38.6 (2016-03-22, [log](https://github.com/Pathoschild/SMAPI/compare/0.38.5...0.38.6))
+* 0.38.5 (2016-03-22, [log](https://github.com/Pathoschild/SMAPI/compare/0.38.4...0.38.5))
+* 0.38.4 (2016-03-21, [log](https://github.com/Pathoschild/SMAPI/compare/0.38.3...0.38.4))
+* 0.38.3 (2016-03-21, [log](https://github.com/Pathoschild/SMAPI/compare/0.38.2...0.38.3))
+* 0.38.2 (2016-03-21, [log](https://github.com/Pathoschild/SMAPI/compare/0.38.0...0.38.2))
+* 0.38.0 (2016-03-20, [log](https://github.com/Pathoschild/SMAPI/compare/0.38.1...0.38.0))
+* 0.38.1 (2016-03-20, [log](https://github.com/Pathoschild/SMAPI/compare/0.37.3...0.38.1))
+* 0.37.3 (2016-03-08, [log](https://github.com/Pathoschild/SMAPI/compare/0.37.2...0.37.3))
+* 0.37.2 (2016-03-07, [log](https://github.com/Pathoschild/SMAPI/compare/0.37.1...0.37.2))
+* 0.37.1 (2016-03-06, [log](https://github.com/Pathoschild/SMAPI/compare/0.36...0.37.1))
+* 0.36 (2016-03-04, [log](https://github.com/Pathoschild/SMAPI/compare/0.37...0.36))
+* 0.37 (2016-03-04, [log](https://github.com/Pathoschild/SMAPI/compare/0.35...0.37))
+* 0.35 (2016-03-02, [log](https://github.com/Pathoschild/SMAPI/compare/0.34...0.35))
+* 0.34 (2016-03-02, [log](https://github.com/Pathoschild/SMAPI/compare/0.33...0.34))
+* 0.33 (2016-03-02, [log](https://github.com/Pathoschild/SMAPI/compare/0.32...0.33))
+* 0.32 (2016-03-02, [log](https://github.com/Pathoschild/SMAPI/compare/0.31...0.32))
+* 0.31 (2016-03-02, [log](https://github.com/Pathoschild/SMAPI/compare/0.3...0.31))
+* 0.3 (2016-03-01, [log](https://github.com/Pathoschild/SMAPI/compare/Alpha0.2...0.3))
+* 0.2 (2016-02-29, [log](https://github.com/Pathoschild/SMAPI/compare/Alpha0.1...Alpha0.2)
* 0.1 (2016-02-28)
diff --git a/src/GlobalAssemblyInfo.cs b/src/GlobalAssemblyInfo.cs
index 0dfb42bb..7f1fa401 100644
--- a/src/GlobalAssemblyInfo.cs
+++ b/src/GlobalAssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.4.0.0")]
-[assembly: AssemblyFileVersion("1.4.0.0")] \ No newline at end of file
+[assembly: AssemblyVersion("1.5.0.0")]
+[assembly: AssemblyFileVersion("1.5.0.0")] \ No newline at end of file
diff --git a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs
index 4cef1a12..5f89caf2 100644
--- a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs
+++ b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs
@@ -55,7 +55,8 @@ namespace StardewModdingApi.Installer
{
// common
"StardewModdingAPI.exe",
- "StardewModdingAPI-settings.json",
+ "StardewModdingAPI.config.json",
+ "StardewModdingAPI.data.json",
"StardewModdingAPI.AssemblyRewriters.dll",
"steam_appid.txt",
@@ -72,7 +73,8 @@ namespace StardewModdingApi.Installer
"StardewModdingAPI.pdb",
// obsolete
- "Mods/.cache"
+ "Mods/.cache", // 1.3-1.4
+ "StardewModdingAPI-settings.json" // 1.0-1.4
};
diff --git a/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj b/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj
index f82bce0f..4e4872b6 100644
--- a/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj
+++ b/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj
@@ -73,7 +73,8 @@
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.exe" DestinationFolder="$(CompiledInstallerPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.exe.mdb" DestinationFolder="$(CompiledInstallerPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.AssemblyRewriters.dll" DestinationFolder="$(CompiledInstallerPath)\Mono" />
- <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI-settings.json" DestinationFolder="$(CompiledInstallerPath)\Mono" />
+ <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(CompiledInstallerPath)\Mono" />
+ <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.data.json" DestinationFolder="$(CompiledInstallerPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Numerics.dll" DestinationFolder="$(CompiledInstallerPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Runtime.Caching.dll" DestinationFolder="$(CompiledInstallerPath)\Mono" />
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\unix-launcher.sh" DestinationFiles="$(CompiledInstallerPath)\Mono\StardewModdingAPI" />
@@ -87,7 +88,8 @@
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.pdb" DestinationFolder="$(CompiledInstallerPath)\Windows" />
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.xml" DestinationFolder="$(CompiledInstallerPath)\Windows" />
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.AssemblyRewriters.dll" DestinationFolder="$(CompiledInstallerPath)\Windows" />
- <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI-settings.json" DestinationFolder="$(CompiledInstallerPath)\Windows" />
+ <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(CompiledInstallerPath)\Windows" />
+ <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.data.json" DestinationFolder="$(CompiledInstallerPath)\Windows" />
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(CompiledInstallerPath)\Windows" />
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="@(CompiledMods)" DestinationFolder="$(CompiledInstallerPath)\Windows\Mods\%(RecursiveDir)" />
</Target>
diff --git a/src/StardewModdingAPI/Constants.cs b/src/StardewModdingAPI/Constants.cs
index f5b9e70a..a79fd382 100644
--- a/src/StardewModdingAPI/Constants.cs
+++ b/src/StardewModdingAPI/Constants.cs
@@ -26,7 +26,11 @@ namespace StardewModdingAPI
** Accessors
*********/
/// <summary>SMAPI's current semantic version.</summary>
- public static readonly Version Version = new Version(1, 4, 0, null);
+ [Obsolete("Use " + nameof(Constants) + "." + nameof(ApiVersion))]
+ public static readonly Version Version = (Version)Constants.ApiVersion;
+
+ /// <summary>SMAPI's current semantic version.</summary>
+ public static ISemanticVersion ApiVersion => new Version(1, 5, 0, null, suppressDeprecationWarning: true);
/// <summary>The minimum supported version of Stardew Valley.</summary>
public const string MinimumGameVersion = "1.1";
@@ -56,7 +60,7 @@ namespace StardewModdingAPI
public static string ExecutionPath => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
/// <summary>The title of the SMAPI console window.</summary>
- public static string ConsoleTitle => $"Stardew Modding API Console - Version {Constants.Version} - Mods Loaded: {Program.ModsLoaded}";
+ public static string ConsoleTitle => $"Stardew Modding API Console - Version {Constants.ApiVersion} - Mods Loaded: {Program.ModsLoaded}";
/// <summary>The directory path in which error logs should be stored.</summary>
public static string LogDir => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley", "ErrorLogs");
@@ -64,6 +68,12 @@ namespace StardewModdingAPI
/// <summary>The file path to the error log where the latest output should be saved.</summary>
public static string LogPath => Path.Combine(Constants.LogDir, "MODDED_ProgramLog.Log_LATEST.txt");
+ /// <summary>The file path for the SMAPI configuration file.</summary>
+ internal static string ApiConfigPath => Path.Combine(Constants.ExecutionPath, $"{typeof(Program).Assembly.GetName().Name}.config.json");
+
+ /// <summary>The file path for the SMAPI data file containing metadata about known mods.</summary>
+ internal static string ApiModMetadataPath => Path.Combine(Constants.ExecutionPath, $"{typeof(Program).Assembly.GetName().Name}.data.json");
+
/*********
** Protected methods
diff --git a/src/StardewModdingAPI/Framework/AssemblyRewriting/CacheEntry.cs b/src/StardewModdingAPI/Framework/AssemblyRewriting/CacheEntry.cs
index 3dfbc78c..a747eaa8 100644
--- a/src/StardewModdingAPI/Framework/AssemblyRewriting/CacheEntry.cs
+++ b/src/StardewModdingAPI/Framework/AssemblyRewriting/CacheEntry.cs
@@ -36,7 +36,7 @@ namespace StardewModdingAPI.Framework.AssemblyRewriting
/// <param name="paths">The paths for the cached assembly.</param>
/// <param name="hash">The MD5 hash of the original assembly.</param>
/// <param name="currentVersion">The current SMAPI version.</param>
- public bool IsUpToDate(CachePaths paths, string hash, Version currentVersion)
+ public bool IsUpToDate(CachePaths paths, string hash, ISemanticVersion currentVersion)
{
return hash == this.Hash
&& this.ApiVersion == currentVersion.ToString()
diff --git a/src/StardewModdingAPI/Framework/ModAssemblyLoader.cs b/src/StardewModdingAPI/Framework/ModAssemblyLoader.cs
index 1ceb8ad2..a2c4ac23 100644
--- a/src/StardewModdingAPI/Framework/ModAssemblyLoader.cs
+++ b/src/StardewModdingAPI/Framework/ModAssemblyLoader.cs
@@ -58,7 +58,7 @@ namespace StardewModdingAPI.Framework
CachePaths cachePaths = this.GetCachePaths(assemblyPath);
{
CacheEntry cacheEntry = File.Exists(cachePaths.Metadata) ? JsonConvert.DeserializeObject<CacheEntry>(File.ReadAllText(cachePaths.Metadata)) : null;
- if (cacheEntry != null && cacheEntry.IsUpToDate(cachePaths, hash, Constants.Version))
+ if (cacheEntry != null && cacheEntry.IsUpToDate(cachePaths, hash, Constants.ApiVersion))
return new RewriteResult(assemblyPath, cachePaths, assemblyBytes, cacheEntry.Hash, cacheEntry.UseCachedAssembly, isNewerThanCache: false); // no rewrite needed
}
this.Monitor.Log($"Preprocessing {Path.GetFileName(assemblyPath)} for compatibility...", LogLevel.Trace);
@@ -99,7 +99,7 @@ namespace StardewModdingAPI.Framework
// cache all results
foreach (RewriteResult result in results)
{
- CacheEntry cacheEntry = new CacheEntry(result.Hash, Constants.Version.ToString(), forceCacheAssemblies || result.UseCachedAssembly);
+ CacheEntry cacheEntry = new CacheEntry(result.Hash, Constants.ApiVersion.ToString(), forceCacheAssemblies || result.UseCachedAssembly);
File.WriteAllText(result.CachePaths.Metadata, JsonConvert.SerializeObject(cacheEntry));
if (forceCacheAssemblies || result.UseCachedAssembly)
File.WriteAllBytes(result.CachePaths.Assembly, result.AssemblyBytes);
diff --git a/src/StardewModdingAPI/Framework/ModRegistry.cs b/src/StardewModdingAPI/Framework/ModRegistry.cs
index ba56a447..b593142d 100644
--- a/src/StardewModdingAPI/Framework/ModRegistry.cs
+++ b/src/StardewModdingAPI/Framework/ModRegistry.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
using System.Reflection;
namespace StardewModdingAPI.Framework
@@ -11,6 +12,9 @@ namespace StardewModdingAPI.Framework
/*********
** Properties
*********/
+ /// <summary>The registered mod data.</summary>
+ private readonly List<IMod> Mods = new List<IMod>();
+
/// <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>();
@@ -19,11 +23,17 @@ namespace StardewModdingAPI.Framework
** Public methods
*********/
/// <summary>Register a mod as a possible source of deprecation warnings.</summary>
- /// <param name="manifest">The mod manifest.</param>
- /// <param name="assembly">The mod assembly.</param>
- public void Add(Manifest manifest, Assembly assembly)
+ /// <param name="mod">The mod instance.</param>
+ public void Add(IMod mod)
+ {
+ this.Mods.Add(mod);
+ this.ModNamesByAssembly[mod.GetType().Assembly.FullName] = mod.ModManifest.Name;
+ }
+
+ /// <summary>Get all enabled mods.</summary>
+ public IEnumerable<IMod> GetMods()
{
- this.ModNamesByAssembly[assembly.FullName] = manifest.Name;
+ return (from mod in this.Mods select mod);
}
/// <summary>Get the friendly name for the closest assembly registered as a source of deprecation warnings.</summary>
diff --git a/src/StardewModdingAPI/Framework/GitRelease.cs b/src/StardewModdingAPI/Framework/Models/GitRelease.cs
index 0da57efd..bc53468f 100644
--- a/src/StardewModdingAPI/Framework/GitRelease.cs
+++ b/src/StardewModdingAPI/Framework/Models/GitRelease.cs
@@ -1,6 +1,6 @@
using Newtonsoft.Json;
-namespace StardewModdingAPI.Framework
+namespace StardewModdingAPI.Framework.Models
{
/// <summary>Metadata about a GitHub release tag.</summary>
internal class GitRelease
diff --git a/src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs b/src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs
new file mode 100644
index 00000000..9bf06552
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs
@@ -0,0 +1,47 @@
+using System.Text.RegularExpressions;
+
+namespace StardewModdingAPI.Framework.Models
+{
+ /// <summary>Contains abstract metadata about an incompatible mod.</summary>
+ internal class IncompatibleMod
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The unique mod ID.</summary>
+ public string ID { get; set; }
+
+ /// <summary>The mod name.</summary>
+ public string Name { get; set; }
+
+ /// <summary>The most recent incompatible mod version.</summary>
+ public string Version { get; set; }
+
+ /// <summary>The URL the user can check for an official updated version.</summary>
+ public string UpdateUrl { get; set; }
+
+ /// <summary>The URL the user can check for an unofficial updated version.</summary>
+ public string UnofficialUpdateUrl { get; set; }
+
+ /// <summary>A regular expression matching version strings to consider compatible, even if they technically precede <see cref="Version"/>.</summary>
+ public string ForceCompatibleVersion { get; set; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Get whether the specified version is compatible according to this metadata.</summary>
+ /// <param name="version">The current version of the matching mod.</param>
+ public bool IsCompatible(ISemanticVersion version)
+ {
+ ISemanticVersion incompatibleVersion = new SemanticVersion(this.Version);
+
+ // allow newer versions
+ if (version.IsNewerThan(incompatibleVersion))
+ return true;
+
+ // allow versions matching override
+ return !string.IsNullOrWhiteSpace(this.ForceCompatibleVersion) && Regex.IsMatch(version.ToString(), this.ForceCompatibleVersion, RegexOptions.IgnoreCase);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/StardewModdingAPI/Framework/Models/UserSettings.cs b/src/StardewModdingAPI/Framework/Models/UserSettings.cs
new file mode 100644
index 00000000..a0074f77
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/Models/UserSettings.cs
@@ -0,0 +1,15 @@
+namespace StardewModdingAPI.Framework.Models
+{
+ /// <summary>Contains user settings from SMAPI's JSON configuration file.</summary>
+ internal class UserSettings
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>Whether to enable development features.</summary>
+ public bool DeveloperMode { get; set; }
+
+ /// <summary>Whether to check if a newer version of SMAPI is available on startup.</summary>
+ public bool CheckForUpdates { get; set; } = true;
+ }
+}
diff --git a/src/StardewModdingAPI/Framework/Reflection/CacheEntry.cs b/src/StardewModdingAPI/Framework/Reflection/CacheEntry.cs
new file mode 100644
index 00000000..30faca37
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/Reflection/CacheEntry.cs
@@ -0,0 +1,30 @@
+using System.Reflection;
+
+namespace StardewModdingAPI.Framework.Reflection
+{
+ /// <summary>A cached member reflection result.</summary>
+ internal struct CacheEntry
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>Whether the lookup found a valid match.</summary>
+ public bool IsValid;
+
+ /// <summary>The reflection data for this member (or <c>null</c> if invalid).</summary>
+ public MemberInfo MemberInfo;
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="isValid">Whether the lookup found a valid match.</param>
+ /// <param name="memberInfo">The reflection data for this member (or <c>null</c> if invalid).</param>
+ public CacheEntry(bool isValid, MemberInfo memberInfo)
+ {
+ this.IsValid = isValid;
+ this.MemberInfo = memberInfo;
+ }
+ }
+}
diff --git a/src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs b/src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs
index 38b4e357..edf59b81 100644
--- a/src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs
+++ b/src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs
@@ -67,10 +67,17 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="obj">The object which has the field.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
- /// <remarks>This is a shortcut for <see cref="GetPrivateField{TValue}(object,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.</remarks>
+ /// <returns>Returns the field value, or the default value for <typeparamref name="TValue"/> if the field wasn't found and <paramref name="required"/> is false.</returns>
+ /// <remarks>
+ /// This is a shortcut for <see cref="GetPrivateField{TValue}(object,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.
+ /// When <paramref name="required" /> is false, this will return the default value if reflection fails. If you need to check whether the field exists, use <see cref="GetPrivateField{TValue}(object,string,bool)" /> instead.
+ /// </remarks>
public TValue GetPrivateValue<TValue>(object obj, string name, bool required = true)
{
- return this.GetPrivateField<TValue>(obj, name, required).GetValue();
+ IPrivateField<TValue> field = this.GetPrivateField<TValue>(obj, name, required);
+ return field != null
+ ? field.GetValue()
+ : default(TValue);
}
/// <summary>Get the value of a private static field.</summary>
@@ -78,10 +85,17 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="type">The type which has the field.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
- /// <remarks>This is a shortcut for <see cref="GetPrivateField{TValue}(Type,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.</remarks>
+ /// <returns>Returns the field value, or the default value for <typeparamref name="TValue"/> if the field wasn't found and <paramref name="required"/> is false.</returns>
+ /// <remarks>
+ /// This is a shortcut for <see cref="GetPrivateField{TValue}(Type,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.
+ /// When <paramref name="required" /> is false, this will return the default value if reflection fails. If you need to check whether the field exists, use <see cref="GetPrivateField{TValue}(Type,string,bool)" /> instead.
+ /// </remarks>
public TValue GetPrivateValue<TValue>(Type type, string name, bool required = true)
{
- return this.GetPrivateField<TValue>(type, name, required).GetValue();
+ IPrivateField<TValue> field = this.GetPrivateField<TValue>(type, name, required);
+ return field != null
+ ? field.GetValue()
+ : default(TValue);
}
/****
@@ -228,12 +242,18 @@ namespace StardewModdingAPI.Framework.Reflection
{
// get from cache
if (this.Cache.Contains(key))
- return (TMemberInfo)this.Cache[key];
+ {
+ CacheEntry entry = (CacheEntry)this.Cache[key];