diff options
| author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-12-27 13:52:32 -0500 |
|---|---|---|
| committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-12-27 13:52:32 -0500 |
| commit | b9dd6eb742e4f0c42ed887abd0f17f113f250056 (patch) | |
| tree | 352a208a25780285419b0bae73148a00a98356ff | |
| parent | c24294c3dd73db3754d10ff8fe5bd51338555638 (diff) | |
| parent | b75d86e7cc19f9bc961abb475f22e8f2b059533c (diff) | |
| download | SMAPI-b9dd6eb742e4f0c42ed887abd0f17f113f250056.tar.gz SMAPI-b9dd6eb742e4f0c42ed887abd0f17f113f250056.tar.bz2 SMAPI-b9dd6eb742e4f0c42ed887abd0f17f113f250056.zip | |
Merge branch 'develop' into stable
31 files changed, 755 insertions, 224 deletions
@@ -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]; |
