diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-03-01 14:10:46 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-03-01 14:10:46 -0500 |
commit | 10c7192bb9f06ff96b9b98a812d9f72a8d77ac76 (patch) | |
tree | 7d4c4ed3498d53e4e8a1c3167fa3937d51b25ecb /src | |
parent | 84b9f4336d5b0c7f269a7bfbb94042360574bbaa (diff) | |
parent | 460b440c2ef4f8c7e2015375fa603095146d1f11 (diff) | |
download | SMAPI-10c7192bb9f06ff96b9b98a812d9f72a8d77ac76.tar.gz SMAPI-10c7192bb9f06ff96b9b98a812d9f72a8d77ac76.tar.bz2 SMAPI-10c7192bb9f06ff96b9b98a812d9f72a8d77ac76.zip |
Merge branch 'develop' into stable
Diffstat (limited to 'src')
-rw-r--r-- | src/SMAPI.Mods.ConsoleCommands/manifest.json | 4 | ||||
-rw-r--r-- | src/SMAPI.Mods.SaveBackup/manifest.json | 4 | ||||
-rw-r--r-- | src/SMAPI.Web/Controllers/IndexController.cs | 3 | ||||
-rw-r--r-- | src/SMAPI.Web/Framework/LogParsing/LogParser.cs | 51 | ||||
-rw-r--r-- | src/SMAPI.Web/Framework/LogParsing/Models/LogModInfo.cs (renamed from src/SMAPI.Web/Framework/LogParsing/Models/ModInfo.cs) | 12 | ||||
-rw-r--r-- | src/SMAPI.Web/Views/LogParser/Index.cshtml | 64 | ||||
-rw-r--r-- | src/SMAPI.Web/wwwroot/Content/css/log-parser.css | 37 | ||||
-rw-r--r-- | src/SMAPI.Web/wwwroot/Content/css/mods.css | 10 | ||||
-rw-r--r-- | src/SMAPI.Web/wwwroot/StardewModdingAPI.metadata.json | 305 | ||||
-rw-r--r-- | src/SMAPI/Constants.cs | 6 | ||||
-rw-r--r-- | src/SMAPI/Framework/Content/AssetDataForDictionary.cs | 6 | ||||
-rw-r--r-- | src/SMAPI/Framework/DeprecationManager.cs | 31 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModHelpers/ModHelper.cs | 2 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/ModResolver.cs | 2 | ||||
-rw-r--r-- | src/SMAPI/Framework/SCore.cs | 2 | ||||
-rw-r--r-- | src/SMAPI/SemanticVersion.cs | 2 |
16 files changed, 310 insertions, 231 deletions
diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json index b5fd0424..afefd733 100644 --- a/src/SMAPI.Mods.ConsoleCommands/manifest.json +++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json @@ -1,9 +1,9 @@ { "Name": "Console Commands", "Author": "SMAPI", - "Version": "2.10.2", + "Version": "2.11.0", "Description": "Adds SMAPI console commands that let you manipulate the game.", "UniqueID": "SMAPI.ConsoleCommands", "EntryDll": "ConsoleCommands.dll", - "MinimumApiVersion": "2.10.2" + "MinimumApiVersion": "2.11.0" } diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json index 7ac537ca..a5841a65 100644 --- a/src/SMAPI.Mods.SaveBackup/manifest.json +++ b/src/SMAPI.Mods.SaveBackup/manifest.json @@ -1,9 +1,9 @@ { "Name": "Save Backup", "Author": "SMAPI", - "Version": "2.10.2", + "Version": "2.11.0", "Description": "Automatically backs up all your saves once per day into its folder.", "UniqueID": "SMAPI.SaveBackup", "EntryDll": "SaveBackup.dll", - "MinimumApiVersion": "2.10.2" + "MinimumApiVersion": "2.11.0" } diff --git a/src/SMAPI.Web/Controllers/IndexController.cs b/src/SMAPI.Web/Controllers/IndexController.cs index 7b3b3e80..ea1a52b2 100644 --- a/src/SMAPI.Web/Controllers/IndexController.cs +++ b/src/SMAPI.Web/Controllers/IndexController.cs @@ -141,6 +141,9 @@ namespace StardewModdingAPI.Web.Controllers foreach (GitAsset asset in release.Assets) { + if (asset.FileName.StartsWith("Z_OLD")) + continue; + Match match = Regex.Match(asset.FileName, @"SMAPI-(?<version>[\d\.]+(?:-.+)?)-installer(?<forDevs>-for-developers)?.zip"); if (!match.Success || !SemanticVersion.TryParse(match.Groups["version"].Value, out ISemanticVersion version)) continue; diff --git a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs index 6f848469..fdc19404 100644 --- a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs +++ b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs @@ -39,6 +39,15 @@ namespace StardewModdingAPI.Web.Framework.LogParsing /// <summary>A regex pattern matching an entry in SMAPI's content pack list.</summary> private readonly Regex ContentPackListEntryPattern = new Regex(@"^ (?<name>.+) (?<version>.+) by (?<author>.+) \| for (?<for>.+?)(?: \| (?<description>.+))?$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + /// <summary>A regex pattern matching the start of SMAPI's mod update list.</summary> + private readonly Regex ModUpdateListStartPattern = new Regex(@"^You can update \d+ mods?:$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + /// <summary>A regex pattern matching an entry in SMAPI's mod update list.</summary> + private readonly Regex ModUpdateListEntryPattern = new Regex(@"^ (?<name>.+?) (?<version>" + SemanticVersion.UnboundedVersionPattern + @"): (?<link>.+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + /// <summary>A regex pattern matching SMAPI's update line.</summary> + private readonly Regex SMAPIUpdatePattern = new Regex(@"^You can update SMAPI to (?<version>" + SemanticVersion.UnboundedVersionPattern + @"): (?<link>.+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + /********* ** Public methods @@ -69,11 +78,12 @@ namespace StardewModdingAPI.Web.Framework.LogParsing }; // parse log messages - LogModInfo smapiMod = new LogModInfo { Name = "SMAPI", Author = "Pathoschild", Description = "" }; - LogModInfo gameMod = new LogModInfo { Name = "game", Author = "", Description = "" }; + LogModInfo smapiMod = new LogModInfo { Name = "SMAPI", Author = "Pathoschild", Description = "", Loaded = true }; + LogModInfo gameMod = new LogModInfo { Name = "game", Author = "", Description = "", Loaded = true }; IDictionary<string, LogModInfo> mods = new Dictionary<string, LogModInfo>(); bool inModList = false; bool inContentPackList = false; + bool inModUpdateList = false; foreach (LogMessage message in log.Messages) { // collect stats @@ -90,11 +100,9 @@ namespace StardewModdingAPI.Web.Framework.LogParsing break; default: - { if (mods.ContainsKey(message.Mod)) mods[message.Mod].Errors++; break; - } } } @@ -106,6 +114,8 @@ namespace StardewModdingAPI.Web.Framework.LogParsing inModList = false; if (inContentPackList && !this.ContentPackListEntryPattern.IsMatch(message.Text)) inContentPackList = false; + if (inModUpdateList && !this.ModUpdateListEntryPattern.IsMatch(message.Text)) + inModUpdateList = false; // mod list if (!inModList && message.Level == LogLevel.Info && this.ModListStartPattern.IsMatch(message.Text)) @@ -117,7 +127,7 @@ namespace StardewModdingAPI.Web.Framework.LogParsing string version = match.Groups["version"].Value; string author = match.Groups["author"].Value; string description = match.Groups["description"].Value; - mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description }; + mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description, Loaded = true }; } // content pack list @@ -131,7 +141,36 @@ namespace StardewModdingAPI.Web.Framework.LogParsing string author = match.Groups["author"].Value; string description = match.Groups["description"].Value; string forMod = match.Groups["for"].Value; - mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description, ContentPackFor = forMod }; + mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description, ContentPackFor = forMod, Loaded = true }; + } + + // mod update list + else if (!inModUpdateList && message.Level == LogLevel.Alert && this.ModUpdateListStartPattern.IsMatch(message.Text)) + inModUpdateList = true; + else if (inModUpdateList) + { + Match match = this.ModUpdateListEntryPattern.Match(message.Text); + string name = match.Groups["name"].Value; + string version = match.Groups["version"].Value; + string link = match.Groups["link"].Value; + if (mods.ContainsKey(name)) + { + mods[name].UpdateLink = link; + mods[name].UpdateVersion = version; + } + else + { + mods[name] = new LogModInfo { Name = name, UpdateVersion = version, UpdateLink = link, Loaded = false }; + } + } + + else if (message.Level == LogLevel.Alert && this.SMAPIUpdatePattern.IsMatch(message.Text)) + { + Match match = this.SMAPIUpdatePattern.Match(message.Text); + string version = match.Groups["version"].Value; + string link = match.Groups["link"].Value; + smapiMod.UpdateVersion = version; + smapiMod.UpdateLink = link; } // platform info line diff --git a/src/SMAPI.Web/Framework/LogParsing/Models/ModInfo.cs b/src/SMAPI.Web/Framework/LogParsing/Models/LogModInfo.cs index 8c84ab38..067e4df4 100644 --- a/src/SMAPI.Web/Framework/LogParsing/Models/ModInfo.cs +++ b/src/SMAPI.Web/Framework/LogParsing/Models/LogModInfo.cs @@ -12,6 +12,12 @@ namespace StardewModdingAPI.Web.Framework.LogParsing.Models /// <summary>The mod author.</summary> public string Author { get; set; } + /// <summary>The update version.</summary> + public string UpdateVersion { get; set; } + + /// <summary>The update link.</summary> + public string UpdateLink { get; set; } + /// <summary>The mod version.</summary> public string Version { get; set; } @@ -23,5 +29,11 @@ namespace StardewModdingAPI.Web.Framework.LogParsing.Models /// <summary>The number of errors logged by this mod.</summary> public int Errors { get; set; } + + /// <summary>Whether the mod was loaded into the game.</summary> + public bool Loaded { get; set; } + + /// <summary>Whether the mod has an update available.</summary> + public bool HasUpdate => this.UpdateVersion != null && this.Version != this.UpdateVersion; } } diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml index 58830d64..21adf35b 100644 --- a/src/SMAPI.Web/Views/LogParser/Index.cshtml +++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml @@ -17,10 +17,10 @@ { <meta name="robots" content="noindex" /> } - <link rel="stylesheet" href="~/Content/css/log-parser.css?r=20180627" /> + <link rel="stylesheet" href="~/Content/css/log-parser.css?r=20190221" /> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js" crossorigin="anonymous"></script> - <script src="~/Content/js/log-parser.js?r=20180627"></script> + <script src="~/Content/js/log-parser.js?r=20190221"></script> <script> $(function() { smapi.logParser({ @@ -117,9 +117,61 @@ else if (Model.ParsedLog?.IsValid == true) @* parsed log *@ @if (Model.ParsedLog?.IsValid == true) { - <h2>Log info</h2> <div id="output"> - <table id="metadata"> + @if (Model.ParsedLog.Mods.Any(mod => mod.HasUpdate)) + { + <h2>Suggested fixes</h2> + <ul id="fix-list"> + <li> + Consider updating these mods to fix problems: + + <table id="updates" class="table"> + @foreach (LogModInfo mod in Model.ParsedLog.Mods.Where(mod => (mod.HasUpdate && mod.ContentPackFor == null) || (contentPacks != null && contentPacks.TryGetValue(mod.Name, out LogModInfo[] contentPackList) && contentPackList.Any(pack => pack.HasUpdate)))) + { + <tr class="mod-entry"> + <td> + <strong class=@(!mod.HasUpdate ? "hidden" : "")>@mod.Name</strong> + @if (contentPacks != null && contentPacks.TryGetValue(mod.Name, out LogModInfo[] contentPackList)) + { + <div class="content-packs"> + @foreach (LogModInfo contentPack in contentPackList.Where(pack => pack.HasUpdate)) + { + <text>+ @contentPack.Name</text><br/> + } + </div> + } + </td> + <td> + @if (mod.HasUpdate) + { + <a href="@mod.UpdateLink" target="_blank"> + @(mod.Version == null ? @mod.UpdateVersion : $"{mod.Version} → {mod.UpdateVersion}") + </a> + } + else + { + <text> </text> + } + + @if (contentPacks != null && contentPacks.TryGetValue(mod.Name, out contentPackList)) + { + <div> + @foreach (LogModInfo contentPack in contentPackList.Where(pack => pack.HasUpdate)) + { + <a href="@contentPack.UpdateLink" target="_blank">@contentPack.Version → @contentPack.UpdateVersion</a><br/> + } + </div> + } + </td> + </tr> + } + </table> + </li> + </ul> + } + + <h2>Log info</h2> + <table id="metadata" class="table"> <caption>Game info:</caption> <tr> <th>Stardew Valley:</th> @@ -139,7 +191,7 @@ else if (Model.ParsedLog?.IsValid == true) </tr> </table> <br /> - <table id="mods" class="@(Model.ShowRaw ? "filters-disabled" : null)"> + <table id="mods" class="@(Model.ShowRaw ? "filters-disabled" : null) table"> <caption> Installed mods: @if (!Model.ShowRaw) @@ -149,7 +201,7 @@ else if (Model.ParsedLog?.IsValid == true) <span class="notice btn txt" v-on:click="hideAllMods" v-bind:class="{ invisible: !anyModsShown || !anyModsHidden }">hide all</span> } </caption> - @foreach (var mod in Model.ParsedLog.Mods.Where(p => p.ContentPackFor == null)) + @foreach (var mod in Model.ParsedLog.Mods.Where(p => p.Loaded && p.ContentPackFor == null)) { <tr v-on:click="toggleMod('@Model.GetSlug(mod.Name)')" class="mod-entry" v-bind:class="{ hidden: !showMods['@Model.GetSlug(mod.Name)'] }"> <td><input type="checkbox" v-bind:checked="showMods['@Model.GetSlug(mod.Name)']" v-bind:class="{ invisible: !anyModsHidden }" /></td> diff --git a/src/SMAPI.Web/wwwroot/Content/css/log-parser.css b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css index 2f3dd0a1..ea28cd7d 100644 --- a/src/SMAPI.Web/wwwroot/Content/css/log-parser.css +++ b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css @@ -13,6 +13,13 @@ caption { #output { padding: 10px; overflow: auto; +} + +#output h2 { + margin: -10px 0 10px -10px; +} + +#output table { font-family: monospace; } @@ -43,7 +50,7 @@ table caption { /********* ** Log metadata & filters *********/ -#metadata, #mods, #filters { +.table, #filters { border-bottom: 1px dashed #888888; margin-bottom: 5px; } @@ -53,7 +60,7 @@ table caption { padding-right: 0.7em; } -table#metadata, table#mods { +.table { border: 1px solid #000000; background: #ffffff; border-radius: 5px; @@ -63,8 +70,20 @@ table#metadata, table#mods { box-shadow: 1px 1px 1px 1px #dddddd; } -.invisible { - visibility: hidden; +.mod-entry { + height: 1.8em; +} + +.table > caption { + min-height: 1.3em; +} + +#fix-list { + margin-bottom: 2em; +} + +#updates { + min-width: 10em; } #mods { @@ -87,8 +106,7 @@ table#metadata, table#mods { cursor: default; } -#metadata tr, -#mods tr { +.table tr { background: #eee } @@ -114,11 +132,11 @@ table#metadata, table#mods { display: inline-block; } -#mods .mod-entry.hidden { +.table .hidden { opacity: 0.5; } -#mods .content-packs { +.table .content-packs { margin-left: 1em; font-size: 0.9em; font-style: italic; @@ -128,8 +146,7 @@ table#metadata, table#mods { padding-right: 5px; } -#metadata tr:nth-child(even), -#mods tr:nth-child(even) { +.table tr:nth-child(even) { background: #fff } diff --git a/src/SMAPI.Web/wwwroot/Content/css/mods.css b/src/SMAPI.Web/wwwroot/Content/css/mods.css index 730bfc2e..f42800da 100644 --- a/src/SMAPI.Web/wwwroot/Content/css/mods.css +++ b/src/SMAPI.Web/wwwroot/Content/css/mods.css @@ -128,8 +128,10 @@ table.wikitable > caption { opacity: 0.7; } -#mod-list .mod-closed-source { - color: red; - font-size: 0.8em; - opacity: 0.5; +#mod-list tr[data-status="abandoned"] .mod-page-links, +#mod-list tr[data-status="broken"] .mod-page-links, +#mod-list tr[data-status="obsolete"] .mod-page-links, +#mod-list tr[data-status="unofficial"] .mod-page-links, +#mod-list tr[data-status="workaround"] .mod-page-links { + text-decoration: line-through; } diff --git a/src/SMAPI.Web/wwwroot/StardewModdingAPI.metadata.json b/src/SMAPI.Web/wwwroot/StardewModdingAPI.metadata.json index 45a4959d..818ff9fe 100644 --- a/src/SMAPI.Web/wwwroot/StardewModdingAPI.metadata.json +++ b/src/SMAPI.Web/wwwroot/StardewModdingAPI.metadata.json @@ -115,22 +115,9 @@ "Default | UpdateKey": "Nexus:1820" }, - /********* - ** Content packs - *********/ - "Canon-Friendly Dialogue Expansion": { - "ID": "gizzymo.canonfriendlyexpansion", - "~1.1.1 | Status": "AssumeBroken" // causes a save crash on certain dates - }, - - "Everytime Submarine": { - "ID": "MustafaDemirel.EverytimeSubmarine", - "~1.0.0 | Status": "AssumeBroken" // breaks player saves if their beach bridge is fixed - }, - /********* - ** Mods + ** Map versions *********/ "Adjust Artisan Prices": { "ID": "ThatNorthernMonkey.AdjustArtisanPrices", @@ -146,28 +133,6 @@ } }, - "Always Scroll Map": { - "ID": "bcmpinc.AlwaysScrollMap", - "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) - }, - - "Animal Mood Fix": { - "ID": "GPeters-AnimalMoodFix", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "the animal mood bugs were fixed in Stardew Valley 1.2." - }, - - "Arcade Pong": { - "ID": "Platonymous.ArcadePong", - "~1.0.2 | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.16 due to reflection into SMAPI internals - }, - - "Automated Doors": { - "ID": "azah.automated-doors", - "FormerIDs": "1abcfa07-2cf4-4dc3-a6e9-6068b642112b", // changed in 1.4.1 - "Default | UpdateKey": "GitHub:azah/AutomatedDoors" // added in 1.4.2 - }, - "Basic Sprinklers Improved": { "ID": "lrsk_sdvm_bsi.0117171308", "MapRemoteVersions": { "1.0.2": "1.0.1-release" } // manifest not updated @@ -184,11 +149,6 @@ "MapRemoteVersions": { "1.3.1": "1.3" } // manifest not updated }, - "BJS Night Sounds": { - "ID": "BunnyJumps.BJSNightSounds", - "~1.0.0 | Status": "AssumeBroken" // runtime errors with Harmony 1.2.0.1 in SMAPI 2.8+ - }, - "Casks Anywhere": { "ID": "CasksAnywhere", "MapLocalVersions": { "1.1-alpha": "1.1" } @@ -199,43 +159,21 @@ "MapLocalVersions": { "1.3-1": "1.3" } }, - "Chest Pooling": { - "ID": "mralbobo.ChestPooling", - "Default | UpdateKey": "GitHub:mralbobo/stardew-chest-pooling" - }, - "Cobalt": { "ID": "spacechase0.Cobalt", "MapRemoteVersions": { "1.1.3": "1.1.2" } // not updated in manifest }, - "Colored Chests": { - "ID": "4befde5c-731c-4853-8e4b-c5cdf946805f", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "colored chests were added in Stardew Valley 1.1." - }, - "Configurable Machines": { "ID": "21da6619-dc03-4660-9794-8e5b498f5b97", "MapLocalVersions": { "1.2-beta": "1.2" } }, - "Craft Counter": { - "ID": "bcmpinc.CraftCounter", - "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) - }, - "Crafting Counter": { "ID": "lolpcgaming.CraftingCounter", "MapRemoteVersions": { "1.1": "1.0" } // not updated in manifest }, - "Custom Farming Automate Bridge": { - "ID": "Platonymous.CFAutomate", - "~1.0.1 | Status": "AssumeBroken", // no longer compatible with Automate - "~1.0.1 | AlternativeUrl": "https://www.nexusmods.com/stardewvalley/mods/991" - }, - "Customizable Cart Redux": { "ID": "KoihimeNakamura.CCR", "MapLocalVersions": { "1.1-20170917": "1.1" } @@ -256,46 +194,6 @@ "MapLocalVersions": { "1.1": "1.1.1" } }, - "Enemy Health Bars": { - "ID": "Speeder.HealthBars", - "FormerIDs": "SPDHealthBar" // changed in 1.7.1-pathoschild-update - }, - - "Fall 28 Snow Day": { - "ID": "Omegasis.Fall28SnowDay", - "~1.4.1 | Status": "AssumeBroken" // broke in SMAPI 2.0, and update for SMAPI 2.0 doesn't do anything - }, - - "Fishing Adjust": { - "ID": "shuaiz.FishingAdjustMod", - "~2.0.1 | Status": "AssumeBroken" // Method not found: 'Void Harmony.HarmonyInstance.Patch(System.Reflection.MethodBase, Harmony.HarmonyMethod, Harmony.HarmonyMethod, Harmony.HarmonyMethod)' - }, - - "Fishing Automaton": { - "ID": "Drynwynn.FishingAutomaton", - "~1.1 | Status": "AssumeBroken" // runtime errors with Harmony 1.2.0.1 in SMAPI 2.8+ - }, - - "Fix Animal Tools": { - "ID": "bcmpinc.FixAnimalTools", - "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) - }, - - "Fix Scythe Exp": { - "ID": "bcmpinc.FixScytheExp", - "~0.3 | Status": "AssumeBroken" // broke in 1.3: Exception from HarmonyInstance "bcmpinc.FixScytheExp" [...] Bad label content in ILGenerator. - }, - - "Gate Opener": { - "ID": "mralbobo.GateOpener", - "Default | UpdateKey": "GitHub:mralbobo/stardew-gate-opener" - }, - - "Grass Growth": { - "ID": "bcmpinc.GrassGrowth", - "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) - }, - "Hunger Mod (skn)": { "ID": "skn.HungerMod", "MapRemoteVersions": { "1.2.1": "1.0" } // manifest not updated @@ -311,32 +209,11 @@ "MapRemoteVersions": { "1.0.1": "1.0" } // manifest not updated }, - "Modder Serialization Utility": { - "ID": "SerializerUtils-0-1", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "it's no longer maintained or used." - }, - - "More Rain": { - "ID": "Omegasis.MoreRain", - "~1.4 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "More Silo Storage": { - "ID": "OrneryWalrus.MoreSiloStorage", - "~1.0.1 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - "Move Faster": { "ID": "shuaiz.MoveFasterMod", "~1.0.1 | Status": "AssumeBroken" // doesn't do anything as of SDV 1.2.33 (bad Harmony patch?) }, - "Movement Speed": { - "ID": "bcmpinc.MovementSpeed", - "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) - }, - "Multiple Sprites and Portraits On Rotation (File Loading)": { "ID": "FileLoading", "MapLocalVersions": { "1.1": "1.12" } @@ -347,33 +224,11 @@ "MapLocalVersions": { "2.1": "1.3" } // 1.3 had wrong version in manifest }, - "No Added Flying Mine Monsters": { - "ID": "Drynwynn.NoAddedFlyingMineMonsters", - "~1.1 | Status": "AssumeBroken" // runtime errors with Harmony 1.2.0.1 in SMAPI 2.8+ - }, - - "No Debug Mode": { - "ID": "NoDebugMode", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "debug mode was removed in SMAPI 1.0." - }, - - "OmniFarm": { - "ID": "PhthaloBlue.OmniFarm", - "FormerIDs": "BlueMod_OmniFarm", // changed in 2.0.2-pathoschild-update - "Default | UpdateKey": "GitHub:lambui/StardewValleyMod_OmniFarm" - }, - "Point-and-Plant": { "ID": "jwdred.PointAndPlant", "MapRemoteVersions": { "1.0.3": "1.0.2" } // manifest not updated }, - "Prairie King Made Easy": { - "ID": "Mucchan.PrairieKingMadeEasy", - "~1.0 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - "Relationship Status": { "ID": "relationshipstatus", "MapRemoteVersions": { "1.0.5": "1.0.4" } // not updated in manifest @@ -384,16 +239,6 @@ "MapLocalVersions": { "1.1.2-release": "1.1.2" } }, - "Save Backup": { - "ID": "Omegasis.SaveBackup", - "~1.2 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Server Bookmarker": { - "ID": "Ilyaki.ServerBookmarker", - "~1.0.0 | Status": "AssumeBroken" // broke in Stardew Valley 1.3.29 (runtime errors) - }, - "Shop Expander": { "ID": "Entoarox.ShopExpander", "FormerIDs": "EntoaroxShopExpander", // changed in 1.5.2 @@ -411,6 +256,123 @@ "MapLocalVersions": { "0.0": "1.4" } }, + "Solar Eclipse Event": { + "ID": "KoihimeNakamura.SolarEclipseEvent", + "MapLocalVersions": { "1.3.1-20180131": "1.3.1" } + }, + + "Time Reminder": { + "ID": "KoihimeNakamura.TimeReminder", + "MapLocalVersions": { "1.0-20170314": "1.0.2" } + }, + + + /********* + ** Obsolete + *********/ + "Animal Mood Fix": { + "ID": "GPeters-AnimalMoodFix", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "the animal mood bugs were fixed in Stardew Valley 1.2." + }, + + "Colored Chests": { + "ID": "4befde5c-731c-4853-8e4b-c5cdf946805f", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "colored chests were added in Stardew Valley 1.1." + }, + + "Modder Serialization Utility": { + "ID": "SerializerUtils-0-1", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "it's no longer maintained or used." + }, + + "No Debug Mode": { + "ID": "NoDebugMode", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "debug mode was removed in SMAPI 1.0." + }, + + + /********* + ** Broke circa SDV 1.3 + *********/ + "Canon-Friendly Dialogue Expansion": { + "ID": "gizzymo.canonfriendlyexpansion", + "~1.1.1 | Status": "AssumeBroken" // causes a save crash on certain dates + }, + + "Everytime Submarine": { + "ID": "MustafaDemirel.EverytimeSubmarine", + "~1.0.0 | Status": "AssumeBroken" // breaks player saves if their beach bridge is fixed + }, + + "Always Scroll Map": { + "ID": "bcmpinc.AlwaysScrollMap", + "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) + }, + + "Arcade Pong": { + "ID": "Platonymous.ArcadePong", + "~1.0.2 | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.16 due to reflection into SMAPI internals + }, + + "BJS Night Sounds": { + "ID": "BunnyJumps.BJSNightSounds", + "~1.0.0 | Status": "AssumeBroken" // runtime errors with Harmony 1.2.0.1 in SMAPI 2.8+ + }, + + "Craft Counter": { + "ID": "bcmpinc.CraftCounter", + "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) + }, + + "Fishing Adjust": { + "ID": "shuaiz.FishingAdjustMod", + "~2.0.1 | Status": "AssumeBroken" // Method not found: 'Void Harmony.HarmonyInstance.Patch(System.Reflection.MethodBase, Harmony.HarmonyMethod, Harmony.HarmonyMethod, Harmony.HarmonyMethod)' + }, + + "Fishing Automaton": { + "ID": "Drynwynn.FishingAutomaton", + "~1.1 | Status": "AssumeBroken" // runtime errors with Harmony 1.2.0.1 in SMAPI 2.8+ + }, + + "Fix Animal Tools": { + "ID": "bcmpinc.FixAnimalTools", + "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) + }, + + "Fix Scythe Exp": { + "ID": "bcmpinc.FixScytheExp", + "~0.3 | Status": "AssumeBroken" // broke in 1.3: Exception from HarmonyInstance "bcmpinc.FixScytheExp" [...] Bad label content in ILGenerator. + }, + + "Grass Growth": { + "ID": "bcmpinc.GrassGrowth", + "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) + }, + + "More Silo Storage": { + "ID": "OrneryWalrus.MoreSiloStorage", + "~1.0.1 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "Movement Speed": { + "ID": "bcmpinc.MovementSpeed", + "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) + }, + + "No Added Flying Mine Monsters": { + "ID": "Drynwynn.NoAddedFlyingMineMonsters", + "~1.1 | Status": "AssumeBroken" // runtime errors with Harmony 1.2.0.1 in SMAPI 2.8+ + }, + + "Server Bookmarker": { + "ID": "Ilyaki.ServerBookmarker", + "~1.0.0 | Status": "AssumeBroken" // broke in Stardew Valley 1.3.29 (runtime errors) + }, + "Skill Prestige: Cooking Adapter": { "ID": "Alphablackwolf.CookingSkillPrestigeAdapter", "FormerIDs": "20d6b8a3-b6e7-460b-a6e4-07c2b0cb6c63", // changed circa 1.1 @@ -423,11 +385,6 @@ "1.3-beta | Status": "AssumeBroken" // doesn't work in multiplayer, no longer maintained }, - "Solar Eclipse Event": { - "ID": "KoihimeNakamura.SolarEclipseEvent", - "MapLocalVersions": { "1.3.1-20180131": "1.3.1" } - }, - "Split Screen": { "ID": "Ilyaki.SplitScreen", "~3.0.1 | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.16 due to reflection into SMAPI internals @@ -438,11 +395,6 @@ "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) }, - "Stardew Notification": { - "ID": "stardewnotification", - "Default | UpdateKey": "GitHub:monopandora/StardewNotification" - }, - "Stephan's Lots of Crops": { "ID": "stephansstardewcrops", "MapRemoteVersions": { "1.41": "1.1" }, // manifest not updated @@ -460,35 +412,14 @@ "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) }, - "Time Reminder": { - "ID": "KoihimeNakamura.TimeReminder", - "MapLocalVersions": { "1.0-20170314": "1.0.2" } - }, - - "Tool Charging": { - "ID": "mralbobo.ToolCharging", - "Default | UpdateKey": "GitHub:mralbobo/stardew-tool-charging" - }, - "Tree Spread": { "ID": "bcmpinc.TreeSpread", "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) }, - "Variable Grass": { - "ID": "dantheman999.VariableGrass", - "Default | UpdateKey": "GitHub:dantheman999301/StardewMods" - }, - "Yet Another Harvest With Scythe Mod": { "ID": "bcmpinc.HarvestWithScythe", "~0.6 | Status": "AssumeBroken" // breaks newer versions of bcmpinc mods (per bcmpinc's request) - }, - - "Zoom Out Extreme": { - "ID": "RockinMods.ZoomMod", - "FormerIDs": "ZoomMod", // changed circa 1.2.1 - "~0.1 | Status": "AssumeBroken" // broke in SDV 1.2 } } } diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 51c15269..d90eecf7 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -20,13 +20,13 @@ namespace StardewModdingAPI ** Public ****/ /// <summary>SMAPI's current semantic version.</summary> - public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("2.10.2"); + public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("2.11.0"); /// <summary>The minimum supported version of Stardew Valley.</summary> - public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.3.32"); + public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.3.36"); /// <summary>The maximum supported version of Stardew Valley.</summary> - public static ISemanticVersion MaximumGameVersion { get; } = new GameVersion("1.3.33"); + public static ISemanticVersion MaximumGameVersion { get; } = null; /// <summary>The target game platform.</summary> public static GamePlatform TargetPlatform => (GamePlatform)Constants.Platform; diff --git a/src/SMAPI/Framework/Content/AssetDataForDictionary.cs b/src/SMAPI/Framework/Content/AssetDataForDictionary.cs index fd3edd5d..11a2564c 100644 --- a/src/SMAPI/Framework/Content/AssetDataForDictionary.cs +++ b/src/SMAPI/Framework/Content/AssetDataForDictionary.cs @@ -26,7 +26,7 @@ namespace StardewModdingAPI.Framework.Content [Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")] public void Set(TKey key, TValue value) { - SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.Info); + SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.PendingRemoval); this.Data[key] = value; } @@ -36,7 +36,7 @@ namespace StardewModdingAPI.Framework.Content [Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")] public void Set(TKey key, Func<TValue, TValue> value) { - SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.Info); + SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.PendingRemoval); this.Data[key] = value(this.Data[key]); } @@ -45,7 +45,7 @@ namespace StardewModdingAPI.Framework.Content [Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")] public void Set(Func<TKey, TValue, TValue> replacer) { - SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.Info); + SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.PendingRemoval); foreach (var pair in this.Data.ToArray()) this.Data[pair.Key] = replacer(pair.Key, pair.Value); } diff --git a/src/SMAPI/Framework/DeprecationManager.cs b/src/SMAPI/Framework/DeprecationManager.cs index fcdf722e..3153bbb4 100644 --- a/src/SMAPI/Framework/DeprecationManager.cs +++ b/src/SMAPI/Framework/DeprecationManager.cs @@ -14,7 +14,11 @@ namespace StardewModdingAPI.Framework private readonly HashSet<string> LoggedDeprecations = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); /// <summary>Encapsulates monitoring and logging for a given module.</summary> +#if !SMAPI_3_0_STRICT + private readonly Monitor Monitor; +#else private readonly IMonitor Monitor; +#endif /// <summary>Tracks the installed mods.</summary> private readonly ModRegistry ModRegistry; @@ -22,6 +26,11 @@ namespace StardewModdingAPI.Framework /// <summary>The queued deprecation warnings to display.</summary> private readonly IList<DeprecationWarning> QueuedWarnings = new List<DeprecationWarning>(); +#if !SMAPI_3_0_STRICT + /// <summary>Whether the one-time deprecation message has been shown.</summary> + private bool DeprecationHeaderShown = false; +#endif + /********* ** Public methods @@ -29,7 +38,11 @@ namespace StardewModdingAPI.Framework /// <summary>Construct an instance.</summary> /// <param name="monitor">Encapsulates monitoring and logging for a given module.</param> /// <param name="modRegistry">Tracks the installed mods.</param> +#if !SMAPI_3_0_STRICT + public DeprecationManager(Monitor monitor, ModRegistry modRegistry) +#else public DeprecationManager(IMonitor monitor, ModRegistry modRegistry) +#endif { this.Monitor = monitor; this.ModRegistry = modRegistry; @@ -38,7 +51,7 @@ namespace StardewModdingAPI.Framework /// <summary>Log a deprecation warning for the old-style events.</summary> public void WarnForOldEvents() { - this.Warn("legacy events", "2.9", DeprecationLevel.Info); + this.Warn("legacy events", "2.9", DeprecationLevel.PendingRemoval); } /// <summary>Log a deprecation warning.</summary> @@ -68,15 +81,25 @@ namespace StardewModdingAPI.Framework /// <summary>Print any queued messages.</summary> public void PrintQueued() { +#if !SMAPI_3_0_STRICT + if (!this.DeprecationHeaderShown && this.QueuedWarnings.Any()) + { + this.Monitor.Newline(); + this.Monitor.Log("Some of your mods will break in the upcoming SMAPI 3.0. Please update your mods now, or notify the author if no update is available. See https://mods.smapi.io for links to the latest versions.", LogLevel.Warn); + this.Monitor.Newline(); + this.DeprecationHeaderShown = true; + } +#endif + foreach (DeprecationWarning warning in this.QueuedWarnings.OrderBy(p => p.ModName).ThenBy(p => p.NounPhrase)) { // build message #if SMAPI_3_0_STRICT - string message = $"{warning.ModName ?? "An unknown mod"} uses deprecated code ({warning.NounPhrase} is deprecated since SMAPI {warning.Version})."; + string message = $"{warning.ModName} uses deprecated code ({warning.NounPhrase} is deprecated since SMAPI {warning.Version})."; #else string message = warning.NounPhrase == "legacy events" - ? $"{warning.ModName ?? "An unknown mod"} uses deprecated code (legacy events are deprecated since SMAPI {warning.Version})." - : $"{warning.ModName ?? "An unknown mod"} uses deprecated code ({warning.NounPhrase} is deprecated since SMAPI {warning.Version})."; + ? $"{warning.ModName ?? "An unknown mod"} will break in the upcoming SMAPI 3.0 (legacy events are deprecated since SMAPI {warning.Version})." + : $"{warning.ModName ?? "An unknown mod"} will break in the upcoming SMAPI 3.0 ({warning.NounPhrase} is deprecated since SMAPI {warning.Version})."; #endif // get log level diff --git a/src/SMAPI/Framework/ModHelpers/ModHelper.cs b/src/SMAPI/Framework/ModHelpers/ModHelper.cs index 18040a78..6c9838c9 100644 --- a/src/SMAPI/Framework/ModHelpers/ModHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ModHelper.cs @@ -166,7 +166,7 @@ namespace StardewModdingAPI.Framework.ModHelpers [Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ContentPacks) + "." + nameof(IContentPackHelper.CreateTemporary) + " instead")] public IContentPack CreateTransitionalContentPack(string directoryPath, string id, string name, string description, string author, ISemanticVersion version) { - SCore.DeprecationManager.Warn($"{nameof(IModHelper)}.{nameof(IModHelper.CreateTransitionalContentPack)}", "2.5", DeprecationLevel.Info); + SCore.DeprecationManager.Warn($"{nameof(IModHelper)}.{nameof(IModHelper.CreateTransitionalContentPack)}", "2.5", DeprecationLevel.PendingRemoval); return this.ContentPacks.CreateTemporary(directoryPath, id, name, description, author, version); } diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index a8564524..75d3849d 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -151,7 +151,7 @@ namespace StardewModdingAPI.Framework.ModLoading mod.SetStatus(ModMetadataStatus.Failed, $"its {nameof(IManifest.EntryDll)} value '{mod.Manifest.EntryDll}' doesn't match the actual file capitalisation '{actualFilename}'. The capitalisation must match for crossplatform compatibility."); continue; #else - SCore.DeprecationManager.Warn(mod.DisplayName, $"{nameof(IManifest.EntryDll)} value with case-insensitive capitalisation", "2.11", DeprecationLevel.Info); + SCore.DeprecationManager.Warn(mod.DisplayName, $"{nameof(IManifest.EntryDll)} value with case-insensitive capitalisation", "2.11", DeprecationLevel.PendingRemoval); #endif } } diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index ec3e9f72..e0347eb2 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -929,7 +929,7 @@ namespace StardewModdingAPI.Framework // add deprecation warning for old version format { if (mod.Manifest?.Version is Toolkit.SemanticVersion version && version.IsLegacyFormat) - SCore.DeprecationManager.Warn(mod.DisplayName, "non-string manifest version", "2.8", DeprecationLevel.Info); + SCore.DeprecationManager.Warn(mod.DisplayName, "non-string manifest version", "2.8", DeprecationLevel.PendingRemoval); } #endif diff --git a/src/SMAPI/SemanticVersion.cs b/src/SMAPI/SemanticVersion.cs index e8e5dfa4..ec2d9e40 100644 --- a/src/SMAPI/SemanticVersion.cs +++ b/src/SMAPI/SemanticVersion.cs @@ -33,7 +33,7 @@ namespace StardewModdingAPI { get { - SCore.DeprecationManager?.Warn($"{nameof(ISemanticVersion)}.{nameof(ISemanticVersion.Build)}", "2.8", DeprecationLevel.Info); + SCore.DeprecationManager?.Warn($"{nameof(ISemanticVersion)}.{nameof(ISemanticVersion.Build)}", "2.8", DeprecationLevel.PendingRemoval); return this.Version.PrereleaseTag; } } |