summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2018-12-16 17:25:58 -0500
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2018-12-16 17:25:58 -0500
commitb214a76965d98ca785b64b490533b6bf66371a48 (patch)
tree76017f8b5762d9cb4e179d32a6b44270e6726051 /src
parent13ed6decf55a7fd72c34b965397011d3012cb9cc (diff)
parentfd0af5f3c149629b91bbe1651a7bda9564b860eb (diff)
downloadSMAPI-b214a76965d98ca785b64b490533b6bf66371a48.tar.gz
SMAPI-b214a76965d98ca785b64b490533b6bf66371a48.tar.bz2
SMAPI-b214a76965d98ca785b64b490533b6bf66371a48.zip
Merge branch 'develop' into stable
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/manifest.json4
-rw-r--r--src/SMAPI.Mods.SaveBackup/manifest.json4
-rw-r--r--src/SMAPI.Web/Startup.cs1
-rw-r--r--src/SMAPI.Web/ViewModels/ModModel.cs8
-rw-r--r--src/SMAPI.Web/Views/Mods/Index.cshtml18
-rw-r--r--src/SMAPI.Web/wwwroot/Content/js/mods.js40
-rw-r--r--src/SMAPI/Constants.cs2
-rw-r--r--src/SMAPI/Events/ContentEvents.cs9
-rw-r--r--src/SMAPI/Events/ControlEvents.cs23
-rw-r--r--src/SMAPI/Events/GameEvents.cs23
-rw-r--r--src/SMAPI/Events/GraphicsEvents.cs21
-rw-r--r--src/SMAPI/Events/InputEvents.cs11
-rw-r--r--src/SMAPI/Events/LocationEvents.cs13
-rw-r--r--src/SMAPI/Events/MenuEvents.cs11
-rw-r--r--src/SMAPI/Events/MineEvents.cs9
-rw-r--r--src/SMAPI/Events/MultiplayerEvents.cs15
-rw-r--r--src/SMAPI/Events/PlayerEvents.cs13
-rw-r--r--src/SMAPI/Events/SaveEvents.cs19
-rw-r--r--src/SMAPI/Events/SpecialisedEvents.cs9
-rw-r--r--src/SMAPI/Events/TimeEvents.cs11
-rw-r--r--src/SMAPI/Framework/Content/AssetDataForDictionary.cs8
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs2
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManager.cs2
-rw-r--r--src/SMAPI/Framework/ModHelpers/CommandHelper.cs2
-rw-r--r--src/SMAPI/Framework/ModHelpers/ContentPackHelper.cs82
-rw-r--r--src/SMAPI/Framework/ModHelpers/ModHelper.cs72
-rw-r--r--src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs7
-rw-r--r--src/SMAPI/Framework/Networking/SGalaxyNetServer.cs24
-rw-r--r--src/SMAPI/Framework/SCore.cs65
-rw-r--r--src/SMAPI/Framework/SGame.cs2
-rw-r--r--src/SMAPI/Framework/SMultiplayer.cs2
-rw-r--r--src/SMAPI/IAssetDataForDictionary.cs8
-rw-r--r--src/SMAPI/ICommandHelper.cs2
-rw-r--r--src/SMAPI/IContentPackHelper.cs27
-rw-r--r--src/SMAPI/IModHelper.cs19
-rw-r--r--src/SMAPI/Metadata/CoreAssetPropagator.cs14
-rw-r--r--src/SMAPI/Patches/ObjectErrorPatch.cs55
-rw-r--r--src/SMAPI/SemanticVersion.cs5
-rw-r--r--src/SMAPI/StardewModdingAPI.csproj5
-rw-r--r--src/StardewModdingAPI.Toolkit.CoreInterfaces/StardewModdingAPI.Toolkit.CoreInterfaces.csproj4
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModExtendedMetadataModel.cs12
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs21
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs6
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiSmapi3Status.cs18
-rw-r--r--src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj4
45 files changed, 454 insertions, 278 deletions
diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json
index fa977039..3d539967 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.9.1",
+ "Version": "2.9.2",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
- "MinimumApiVersion": "2.9.1"
+ "MinimumApiVersion": "2.9.2"
}
diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json
index 1875adca..20935880 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.9.1",
+ "Version": "2.9.2",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
- "MinimumApiVersion": "2.9.1"
+ "MinimumApiVersion": "2.9.2"
}
diff --git a/src/SMAPI.Web/Startup.cs b/src/SMAPI.Web/Startup.cs
index 0bd71d26..4e3aaed3 100644
--- a/src/SMAPI.Web/Startup.cs
+++ b/src/SMAPI.Web/Startup.cs
@@ -165,6 +165,7 @@ namespace StardewModdingAPI.Web
redirects.Add(new RedirectToUrlRule(@"^/3\.0\.?$", "https://stardewvalleywiki.com/Modding:Migrate_to_SMAPI_3.0"));
redirects.Add(new RedirectToUrlRule(@"^/docs\.?$", "https://stardewvalleywiki.com/Modding:Index"));
redirects.Add(new RedirectToUrlRule(@"^/install\.?$", "https://stardewvalleywiki.com/Modding:Player_Guide/Getting_Started#Install_SMAPI"));
+ redirects.Add(new RedirectToUrlRule(@"^/troubleshoot(.*)$", "https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting$1"));
// redirect legacy canimod.com URLs
var wikiRedirects = new Dictionary<string, string[]>
diff --git a/src/SMAPI.Web/ViewModels/ModModel.cs b/src/SMAPI.Web/ViewModels/ModModel.cs
index 5c1840fc..f1a52f98 100644
--- a/src/SMAPI.Web/ViewModels/ModModel.cs
+++ b/src/SMAPI.Web/ViewModels/ModModel.cs
@@ -31,6 +31,12 @@ namespace StardewModdingAPI.Web.ViewModels
/// <summary>The compatibility status for the beta version of the game.</summary>
public ModCompatibilityModel BetaCompatibility { get; set; }
+ /// <summary>Whether the mod is ready for the upcoming SMAPI 3.0.</summary>
+ public string Smapi3Status { get; set; }
+
+ /// <summary>A URL related to the <see cref="Smapi3Status"/>.</summary>
+ public string Smapi3Url { get; set; }
+
/// <summary>Links to the available mod pages.</summary>
public ModLinkModel[] ModPages { get; set; }
@@ -59,6 +65,8 @@ namespace StardewModdingAPI.Web.ViewModels
this.SourceUrl = this.GetSourceUrl(entry);
this.Compatibility = new ModCompatibilityModel(entry.Compatibility);
this.BetaCompatibility = entry.BetaCompatibility != null ? new ModCompatibilityModel(entry.BetaCompatibility) : null;
+ this.Smapi3Status = entry.Smapi3Status.ToString().ToLower();
+ this.Smapi3Url = entry.Smapi3Url;
this.ModPages = this.GetModPageUrls(entry).ToArray();
this.Warnings = entry.Warnings;
this.Slug = entry.Anchor;
diff --git a/src/SMAPI.Web/Views/Mods/Index.cshtml b/src/SMAPI.Web/Views/Mods/Index.cshtml
index a49a24d9..a6c94cf1 100644
--- a/src/SMAPI.Web/Views/Mods/Index.cshtml
+++ b/src/SMAPI.Web/Views/Mods/Index.cshtml
@@ -45,7 +45,10 @@
</div>
</div>
<div id="mod-count" v-show="showAdvanced">
- <span v-if="visibleStats.total > 0">{{visibleStats.total}} mods shown ({{Math.round((visibleStats.compatible + visibleStats.workaround) / visibleStats.total * 100)}}% compatible or have a workaround, {{Math.round((visibleStats.soon + visibleStats.broken) / visibleStats.total * 100)}}% broken, {{Math.round(visibleStats.abandoned / visibleStats.total * 100)}}% obsolete).</span>
+ <div v-if="visibleStats.total > 0">
+ {{visibleStats.total}} mods shown ({{Math.round((visibleStats.compatible + visibleStats.workaround) / visibleStats.total * 100)}}% compatible or have a workaround, {{Math.round((visibleStats.soon + visibleStats.broken) / visibleStats.total * 100)}}% broken, {{Math.round(visibleStats.abandoned / visibleStats.total * 100)}}% obsolete).<br />
+ SMAPI 3.0 (upcoming): {{Math.round(visibleStats.smapi3_ok / visibleStats.total * 100)}}% ready, {{Math.round(visibleStats.smapi3_soon / visibleStats.total * 100)}}% soon, {{Math.round(visibleStats.smapi3_broken / visibleStats.total * 100)}}% broken, {{Math.round(visibleStats.smapi3_unknown / visibleStats.total * 100)}}% unknown.
+ </div>
<span v-else>No matching mods found.</span>
</div>
<table class="wikitable" id="mod-list">
@@ -57,11 +60,12 @@
<th>compatibility</th>
<th v-show="showAdvanced">broke in</th>
<th v-show="showAdvanced">code</th>
+ <th v-show="showAdvanced"><a href="http://smapi.io/3.0">3.0</a></th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
- <tr v-for="mod in mods" :key="mod.Name" v-bind:id="mod.Slug" :key="mod.Slug" v-bind:data-status="mod.BetaCompatibility != null ? mod.BetaCompatibility.Status : mod.Compatibility.Status" v-show="mod.Visible">
+ <tr v-for="mod in mods" :key="mod.Name" v-bind:id="mod.Slug" :key="mod.Slug" v-bind:data-status="mod.LatestCompatibility.Status" v-show="mod.Visible">
<td>
{{mod.Name}}
<small class="mod-alt-names" v-if="mod.AlternateNames">(aka {{mod.AlternateNames}})</small>
@@ -83,11 +87,19 @@
</div>
<div v-for="(warning, i) in mod.Warnings">⚠ {{warning}}</div>
</td>
- <td class="mod-broke-in" v-html="mod.BetaCompatibility ? mod.BetaCompatibility.BrokeIn : mod.Compatibility.BrokeIn" v-show="showAdvanced"></td>
+ <td class="mod-broke-in" v-html="mod.LatestCompatibility.BrokeIn" v-show="showAdvanced"></td>
<td v-show="showAdvanced">
<span v-if="mod.SourceUrl"><a v-bind:href="mod.SourceUrl">source</a></span>
<span v-else class="mod-closed-source">no source</span>
</td>
+ <td v-show="showAdvanced">
+ <template v-if="mod.LatestCompatibility.Status == 'ok' || mod.LatestCompatibility.Status == 'unofficial' || mod.Smapi3Status == 'ok' || mod.Smapi3Status == 'soon'">
+ <small v-if="mod.Smapi3Status == 'ok'">✓</small>
+ <small v-else-if="mod.Smapi3Status == 'broken'">✖</small>
+ <small v-else-if="mod.Smapi3Status == 'soon' && mod.Smapi3Url"><a v-bind:href="mod.Smapi3Url">↻ soon</a></small>
+ <small v-else>↻ {{mod.Smapi3Status}}</small>
+ </template>
+ </td>
<td>
<small><a v-bind:href="'#' + mod.Slug">#</a></small>
</td>
diff --git a/src/SMAPI.Web/wwwroot/Content/js/mods.js b/src/SMAPI.Web/wwwroot/Content/js/mods.js
index f7a8501e..28992908 100644
--- a/src/SMAPI.Web/wwwroot/Content/js/mods.js
+++ b/src/SMAPI.Web/wwwroot/Content/js/mods.js
@@ -11,7 +11,11 @@ smapi.modList = function (mods) {
soon: 0,
broken: 0,
abandoned: 0,
- invalid: 0
+ invalid: 0,
+ smapi3_unknown: 0,
+ smapi3_ok: 0,
+ smapi3_broken: 0,
+ smapi3_soon: 0
};
var data = {
mods: mods,
@@ -88,6 +92,28 @@ smapi.modList = function (mods) {
id: "show-custom",
value: true
}
+ },
+ "SMAPI 3.0": {
+ ok: {
+ label: "ready",
+ id: "show-smapi-3-ready",
+ value: true
+ },
+ soon: {
+ label: "soon",
+ id: "show-smapi-3-soon",
+ value: true
+ },
+ broken: {
+ label: "broken",
+ id: "show-smapi-3-broken",
+ value: true
+ },
+ unknown: {
+ label: "unknown",
+ id: "show-smapi-3-unknown",
+ value: true
+ }
}
},
search: ""
@@ -98,6 +124,9 @@ smapi.modList = function (mods) {
// set initial visibility
mod.Visible = true;
+ // set overall compatibility
+ mod.LatestCompatibility = mod.BetaCompatibility || mod.Compatibility;
+
// concatenate searchable text
mod.SearchableText = [mod.Name, mod.AlternateNames, mod.Author, mod.AlternateAuthors, mod.Compatibility.Summary, mod.BrokeIn];
if (mod.Compatibility.UnofficialVersion)
@@ -154,6 +183,7 @@ smapi.modList = function (mods) {
if (mod.Visible) {
stats.total++;
stats[this.getCompatibilityGroup(mod)]++;
+ stats["smapi3_" + mod.Smapi3Status]++;
}
}
},
@@ -175,10 +205,14 @@ smapi.modList = function (mods) {
return false;
// check status
- var status = (mod.BetaCompatibility || mod.Compatibility).Status;
+ var status = mod.LatestCompatibility.Status;
if (filters.status[status] && !filters.status[status].value)
return false;
+ // check SMAPI 3.0 compatibility
+ if (filters["SMAPI 3.0"][mod.Smapi3Status] && !filters["SMAPI 3.0"][mod.Smapi3Status].value)
+ return false;
+
// check download sites
var ignoreSites = [];
@@ -219,7 +253,7 @@ smapi.modList = function (mods) {
* @returns {string} The compatibility group (one of 'compatible', 'workaround', 'soon', 'broken', 'abandoned', or 'invalid').
*/
getCompatibilityGroup: function (mod) {
- var status = (mod.BetaCompatibility || mod.Compatibility).Status;
+ var status = mod.LatestCompatibility.Status;
switch (status) {
// obsolete
case "abandoned":
diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs
index 959ab3c7..13c30032 100644
--- a/src/SMAPI/Constants.cs
+++ b/src/SMAPI/Constants.cs
@@ -29,7 +29,7 @@ namespace StardewModdingAPI
** Public
****/
/// <summary>SMAPI's current semantic version.</summary>
- public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("2.9.1");
+ public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("2.9.2");
/// <summary>The minimum supported version of Stardew Valley.</summary>
public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.3.32");
diff --git a/src/SMAPI/Events/ContentEvents.cs b/src/SMAPI/Events/ContentEvents.cs
index 99369cae..1a2dd526 100644
--- a/src/SMAPI/Events/ContentEvents.cs
+++ b/src/SMAPI/Events/ContentEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- ContentEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
ContentEvents.EventManager.Legacy_LocaleChanged.Add(value);
}
remove => ContentEvents.EventManager.Legacy_LocaleChanged.Remove(value);
@@ -39,11 +36,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
ContentEvents.EventManager = eventManager;
- ContentEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/ControlEvents.cs b/src/SMAPI/Events/ControlEvents.cs
index 5626ff81..be849f95 100644
--- a/src/SMAPI/Events/ControlEvents.cs
+++ b/src/SMAPI/Events/ControlEvents.cs
@@ -16,9 +16,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -28,7 +25,7 @@ namespace StardewModdingAPI.Events
{
add
{
- ControlEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_KeyboardChanged.Add(value);
}
remove => ControlEvents.EventManager.Legacy_KeyboardChanged.Remove(value);
@@ -39,7 +36,7 @@ namespace StardewModdingAPI.Events
{
add
{
- ControlEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_KeyPressed.Add(value);
}
remove => ControlEvents.EventManager.Legacy_KeyPressed.Remove(value);
@@ -50,7 +47,7 @@ namespace StardewModdingAPI.Events
{
add
{
- ControlEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_KeyReleased.Add(value);
}
remove => ControlEvents.EventManager.Legacy_KeyReleased.Remove(value);
@@ -61,7 +58,7 @@ namespace StardewModdingAPI.Events
{
add
{
- ControlEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_MouseChanged.Add(value);
}
remove => ControlEvents.EventManager.Legacy_MouseChanged.Remove(value);
@@ -72,7 +69,7 @@ namespace StardewModdingAPI.Events
{
add
{
- ControlEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerButtonPressed.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerButtonPressed.Remove(value);
@@ -83,7 +80,7 @@ namespace StardewModdingAPI.Events
{
add
{
- ControlEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerButtonReleased.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerButtonReleased.Remove(value);
@@ -94,7 +91,7 @@ namespace StardewModdingAPI.Events
{
add
{
- ControlEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerTriggerPressed.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerTriggerPressed.Remove(value);
@@ -105,7 +102,7 @@ namespace StardewModdingAPI.Events
{
add
{
- ControlEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerTriggerReleased.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerTriggerReleased.Remove(value);
@@ -117,11 +114,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
ControlEvents.EventManager = eventManager;
- ControlEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/GameEvents.cs b/src/SMAPI/Events/GameEvents.cs
index 39b77f99..6069a185 100644
--- a/src/SMAPI/Events/GameEvents.cs
+++ b/src/SMAPI/Events/GameEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GameEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_UpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_UpdateTick.Remove(value);
@@ -38,7 +35,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GameEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_SecondUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_SecondUpdateTick.Remove(value);
@@ -49,7 +46,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GameEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_FourthUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_FourthUpdateTick.Remove(value);
@@ -60,7 +57,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GameEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_EighthUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_EighthUpdateTick.Remove(value);
@@ -71,7 +68,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GameEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_QuarterSecondTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_QuarterSecondTick.Remove(value);
@@ -82,7 +79,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GameEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_HalfSecondTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_HalfSecondTick.Remove(value);
@@ -93,7 +90,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GameEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_OneSecondTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_OneSecondTick.Remove(value);
@@ -104,7 +101,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GameEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_FirstUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_FirstUpdateTick.Remove(value);
@@ -116,11 +113,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
GameEvents.EventManager = eventManager;
- GameEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/GraphicsEvents.cs b/src/SMAPI/Events/GraphicsEvents.cs
index be29bf11..88a32c3f 100644
--- a/src/SMAPI/Events/GraphicsEvents.cs
+++ b/src/SMAPI/Events/GraphicsEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GraphicsEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_Resize.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_Resize.Remove(value);
@@ -41,7 +38,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GraphicsEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPreRenderEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPreRenderEvent.Remove(value);
@@ -52,7 +49,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GraphicsEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPostRenderEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPostRenderEvent.Remove(value);
@@ -66,7 +63,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GraphicsEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPreRenderHudEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPreRenderHudEvent.Remove(value);
@@ -77,7 +74,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GraphicsEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPostRenderHudEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPostRenderHudEvent.Remove(value);
@@ -91,7 +88,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GraphicsEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPreRenderGuiEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPreRenderGuiEvent.Remove(value);
@@ -102,7 +99,7 @@ namespace StardewModdingAPI.Events
{
add
{
- GraphicsEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPostRenderGuiEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPostRenderGuiEvent.Remove(value);
@@ -114,11 +111,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
GraphicsEvents.EventManager = eventManager;
- GraphicsEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/InputEvents.cs b/src/SMAPI/Events/InputEvents.cs
index 255b9c8a..900e53ea 100644
--- a/src/SMAPI/Events/InputEvents.cs
+++ b/src/SMAPI/Events/InputEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- InputEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
InputEvents.EventManager.Legacy_ButtonPressed.Add(value);
}
remove => InputEvents.EventManager.Legacy_ButtonPressed.Remove(value);
@@ -38,7 +35,7 @@ namespace StardewModdingAPI.Events
{
add
{
- InputEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
InputEvents.EventManager.Legacy_ButtonReleased.Add(value);
}
remove => InputEvents.EventManager.Legacy_ButtonReleased.Remove(value);
@@ -50,11 +47,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
InputEvents.EventManager = eventManager;
- InputEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/LocationEvents.cs b/src/SMAPI/Events/LocationEvents.cs
index e0bcd853..5eb228b7 100644
--- a/src/SMAPI/Events/LocationEvents.cs
+++ b/src/SMAPI/Events/LocationEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- LocationEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
LocationEvents.EventManager.Legacy_LocationsChanged.Add(value);
}
remove => LocationEvents.EventManager.Legacy_LocationsChanged.Remove(value);
@@ -38,7 +35,7 @@ namespace StardewModdingAPI.Events
{
add
{
- LocationEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
LocationEvents.EventManager.Legacy_BuildingsChanged.Add(value);
}
remove => LocationEvents.EventManager.Legacy_BuildingsChanged.Remove(value);
@@ -49,7 +46,7 @@ namespace StardewModdingAPI.Events
{
add
{
- LocationEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
LocationEvents.EventManager.Legacy_ObjectsChanged.Add(value);
}
remove => LocationEvents.EventManager.Legacy_ObjectsChanged.Remove(value);
@@ -61,11 +58,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
LocationEvents.EventManager = eventManager;
- LocationEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/MenuEvents.cs b/src/SMAPI/Events/MenuEvents.cs
index e36cb498..914948dd 100644
--- a/src/SMAPI/Events/MenuEvents.cs
+++ b/src/SMAPI/Events/MenuEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- MenuEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
MenuEvents.EventManager.Legacy_MenuChanged.Add(value);
}
remove => MenuEvents.EventManager.Legacy_MenuChanged.Remove(value);
@@ -38,7 +35,7 @@ namespace StardewModdingAPI.Events
{
add
{
- MenuEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
MenuEvents.EventManager.Legacy_MenuClosed.Add(value);
}
remove => MenuEvents.EventManager.Legacy_MenuClosed.Remove(value);
@@ -50,11 +47,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
MenuEvents.EventManager = eventManager;
- MenuEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/MineEvents.cs b/src/SMAPI/Events/MineEvents.cs
index 954c844a..fd35237e 100644
--- a/src/SMAPI/Events/MineEvents.cs
+++ b/src/SMAPI/Events/MineEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- MineEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
MineEvents.EventManager.Legacy_MineLevelChanged.Add(value);
}
remove => MineEvents.EventManager.Legacy_MineLevelChanged.Remove(value);
@@ -39,11 +36,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
MineEvents.EventManager = eventManager;
- MineEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/MultiplayerEvents.cs b/src/SMAPI/Events/MultiplayerEvents.cs
index 7e8328a4..5e6a22dc 100644
--- a/src/SMAPI/Events/MultiplayerEvents.cs
+++ b/src/SMAPI/Events/MultiplayerEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- MultiplayerEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_BeforeMainSync.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_BeforeMainSync.Remove(value);
@@ -38,7 +35,7 @@ namespace StardewModdingAPI.Events
{
add
{
- MultiplayerEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_AfterMainSync.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_AfterMainSync.Remove(value);
@@ -49,7 +46,7 @@ namespace StardewModdingAPI.Events
{
add
{
- MultiplayerEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_BeforeMainBroadcast.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_BeforeMainBroadcast.Remove(value);
@@ -60,7 +57,7 @@ namespace StardewModdingAPI.Events
{
add
{
- MultiplayerEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_AfterMainBroadcast.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_AfterMainBroadcast.Remove(value);
@@ -72,11 +69,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
MultiplayerEvents.EventManager = eventManager;
- MultiplayerEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/PlayerEvents.cs b/src/SMAPI/Events/PlayerEvents.cs
index 1193675f..98bc3da5 100644
--- a/src/SMAPI/Events/PlayerEvents.cs
+++ b/src/SMAPI/Events/PlayerEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- PlayerEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
PlayerEvents.EventManager.Legacy_InventoryChanged.Add(value);
}
remove => PlayerEvents.EventManager.Legacy_InventoryChanged.Remove(value);
@@ -38,7 +35,7 @@ namespace StardewModdingAPI.Events
{
add
{
- PlayerEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
PlayerEvents.EventManager.Legacy_LeveledUp.Add(value);
}
remove => PlayerEvents.EventManager.Legacy_LeveledUp.Remove(value);
@@ -49,7 +46,7 @@ namespace StardewModdingAPI.Events
{
add
{
- PlayerEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
PlayerEvents.EventManager.Legacy_PlayerWarped.Add(value);
}
remove => PlayerEvents.EventManager.Legacy_PlayerWarped.Remove(value);
@@ -62,11 +59,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
PlayerEvents.EventManager = eventManager;
- PlayerEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/SaveEvents.cs b/src/SMAPI/Events/SaveEvents.cs
index 156d3047..959fb5d2 100644
--- a/src/SMAPI/Events/SaveEvents.cs
+++ b/src/SMAPI/Events/SaveEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- SaveEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_BeforeCreateSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_BeforeCreateSave.Remove(value);
@@ -38,7 +35,7 @@ namespace StardewModdingAPI.Events
{
add
{
- SaveEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterCreateSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterCreateSave.Remove(value);
@@ -49,7 +46,7 @@ namespace StardewModdingAPI.Events
{
add
{
- SaveEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_BeforeSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_BeforeSave.Remove(value);
@@ -60,7 +57,7 @@ namespace StardewModdingAPI.Events
{
add
{
- SaveEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterSave.Remove(value);
@@ -71,7 +68,7 @@ namespace StardewModdingAPI.Events
{
add
{
- SaveEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterLoad.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterLoad.Remove(value);
@@ -82,7 +79,7 @@ namespace StardewModdingAPI.Events
{
add
{
- SaveEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterReturnToTitle.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterReturnToTitle.Remove(value);
@@ -94,11 +91,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
SaveEvents.EventManager = eventManager;
- SaveEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/SpecialisedEvents.cs b/src/SMAPI/Events/SpecialisedEvents.cs
index 0dd726e9..2c6d0230 100644
--- a/src/SMAPI/Events/SpecialisedEvents.cs
+++ b/src/SMAPI/Events/SpecialisedEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- SpecialisedEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
SpecialisedEvents.EventManager.Legacy_UnvalidatedUpdateTick.Add(value);
}
remove => SpecialisedEvents.EventManager.Legacy_UnvalidatedUpdateTick.Remove(value);
@@ -39,11 +36,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
SpecialisedEvents.EventManager = eventManager;
- SpecialisedEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Events/TimeEvents.cs b/src/SMAPI/Events/TimeEvents.cs
index 61491dc8..40892491 100644
--- a/src/SMAPI/Events/TimeEvents.cs
+++ b/src/SMAPI/Events/TimeEvents.cs
@@ -15,9 +15,6 @@ namespace StardewModdingAPI.Events
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
- /// <summary>Manages deprecation warnings.</summary>
- private static DeprecationManager DeprecationManager;
-
/*********
** Events
@@ -27,7 +24,7 @@ namespace StardewModdingAPI.Events
{
add
{
- TimeEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
TimeEvents.EventManager.Legacy_AfterDayStarted.Add(value);
}
remove => TimeEvents.EventManager.Legacy_AfterDayStarted.Remove(value);
@@ -38,7 +35,7 @@ namespace StardewModdingAPI.Events
{
add
{
- TimeEvents.DeprecationManager.WarnForOldEvents();
+ SCore.DeprecationManager.WarnForOldEvents();
TimeEvents.EventManager.Legacy_TimeOfDayChanged.Add(value);
}
remove => TimeEvents.EventManager.Legacy_TimeOfDayChanged.Remove(value);
@@ -50,11 +47,9 @@ namespace StardewModdingAPI.Events
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- internal static void Init(EventManager eventManager, DeprecationManager deprecationManager)
+ internal static void Init(EventManager eventManager)
{
TimeEvents.EventManager = eventManager;
- TimeEvents.DeprecationManager = deprecationManager;
}
}
}
diff --git a/src/SMAPI/Framework/Content/AssetDataForDictionary.cs b/src/SMAPI/Framework/Content/AssetDataForDictionary.cs
index 7b80875f..9bd70711 100644
--- a/src/SMAPI/Framework/Content/AssetDataForDictionary.cs
+++ b/src/SMAPI/Framework/Content/AssetDataForDictionary.cs
@@ -19,28 +19,36 @@ namespace StardewModdingAPI.Framework.Content
public AssetDataForDictionary(string locale, string assetName, IDictionary<TKey, TValue> data, Func<string, string> getNormalisedPath, Action<IDictionary<TKey, TValue>> onDataReplaced)
: base(locale, assetName, data, getNormalisedPath, onDataReplaced) { }
+#if !SMAPI_3_0_STRICT
/// <summary>Add or replace an entry in the dictionary.</summary>
/// <param name="key">The entry key.</param>
/// <param name="value">The entry value.</param>
+ [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.Notice);
this.Data[key] = value;
}
/// <summary>Add or replace an entry in the dictionary.</summary>
/// <param name="key">The entry key.</param>
/// <param name="value">A callback which accepts the current value and returns the new value.</param>
+ [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.Notice);
this.Data[key] = value(this.Data[key]);
}
/// <summary>Dynamically replace values in the dictionary.</summary>
/// <param name="replacer">A lambda which takes the current key and value for an entry, and returns the new value.</param>
+ [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.Notice);
foreach (var pair in this.Data.ToArray())
this.Data[pair.Key] = replacer(pair.Key, pair.Value);
}
+#endif
}
}
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index 08a32a9b..7e256939 100644
--- a/src/SMAPI/Framework/ContentCoordinator.cs
+++ b/src/SMAPI/Framework/ContentCoordinator.cs
@@ -81,7 +81,7 @@ namespace StardewModdingAPI.Framework
this.ContentManagers.Add(
this.MainContentManager = new GameContentManager("Game1.content", serviceProvider, rootDirectory, currentCulture, this, monitor, reflection, this.OnDisposing)
);
- this.CoreAssets = new CoreAssetPropagator(this.MainContentManager.AssertAndNormaliseAssetName, reflection);
+ this.CoreAssets = new CoreAssetPropagator(this.MainContentManager.AssertAndNormaliseAssetName, reflection, monitor);
}
/// <summary>Get a new content manager which handles reading files from the game content folder with support for interception.</summary>
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
index 4f3b6fbc..81732d3f 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
@@ -238,7 +238,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
try
{
editor.Edit<T>(asset);
- this.Monitor.Log($"{mod.DisplayName} intercepted {info.AssetName}.", LogLevel.Trace);
+ this.Monitor.Log($"{mod.DisplayName} edited {info.AssetName}.", LogLevel.Trace);
}
catch (Exception ex)
{
diff --git a/src/SMAPI/Framework/ModHelpers/CommandHelper.cs b/src/SMAPI/Framework/ModHelpers/CommandHelper.cs
index 5a3304f3..a4fd21c1 100644
--- a/src/SMAPI/Framework/ModHelpers/CommandHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/CommandHelper.cs
@@ -6,7 +6,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
internal class CommandHelper : BaseHelper, ICommandHelper
{
/*********
- ** Accessors
+ ** Properties
*********/
/// <summary>The mod using this instance.</summary>
private readonly IModMetadata Mod;
diff --git a/src/SMAPI/Framework/ModHelpers/ContentPackHelper.cs b/src/SMAPI/Framework/ModHelpers/ContentPackHelper.cs
new file mode 100644
index 00000000..26c4648c
--- /dev/null
+++ b/src/SMAPI/Framework/ModHelpers/ContentPackHelper.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using StardewModdingAPI.Toolkit.Serialisation.Models;
+
+namespace StardewModdingAPI.Framework.ModHelpers
+{
+ /// <summary>Provides an API for managing content packs.</summary>
+ internal class ContentPackHelper : BaseHelper, IContentPackHelper
+ {
+ /*********
+ ** Properties
+ *********/
+ /// <summary>The content packs loaded for this mod.</summary>
+ private readonly Lazy<IContentPack[]> ContentPacks;
+
+ /// <summary>Create a temporary content pack.</summary>
+ private readonly Func<string, IManifest, IContentPack> CreateContentPack;
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="modID">The unique ID of the relevant mod.</param>
+ /// <param name="contentPacks">The content packs loaded for this mod.</param>
+ /// <param name="createContentPack">Create a temporary content pack.</param>
+ public ContentPackHelper(string modID, Lazy<IContentPack[]> contentPacks, Func<string, IManifest, IContentPack> createContentPack)
+ : base(modID)
+ {
+ this.ContentPacks = contentPacks;
+ this.CreateContentPack = createContentPack;
+ }
+
+ /// <summary>Get all content packs loaded for this mod.</summary>
+ public IEnumerable<IContentPack> GetOwned()
+ {
+ return this.ContentPacks.Value;
+ }
+
+ /// <summary>Create a temporary content pack to read files from a directory, using randomised manifest fields. This will generate fake manifest data; any <c>manifest.json</c> in the directory will be ignored. Temporary content packs will not appear in the SMAPI log and update checks will not be performed.</summary>
+ /// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
+ public IContentPack CreateFake(string directoryPath)
+ {
+ string id = Guid.NewGuid().ToString("N");
+ return this.CreateTemporary(directoryPath, id, id, id, id, new SemanticVersion(1, 0, 0));
+ }
+
+ /// <summary>Create a temporary content pack to read files from a directory. Temporary content packs will not appear in the SMAPI log and update checks will not be performed.</summary>
+ /// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
+ /// <param name="id">The content pack's unique ID.</param>
+ /// <param name="name">The content pack name.</param>
+ /// <param name="description">The content pack description.</param>
+ /// <param name="author">The content pack author's name.</param>
+ /// <param name="version">The content pack version.</param>
+ public IContentPack CreateTemporary(string directoryPath, string id, string name, string description, string author, ISemanticVersion version)
+ {
+ // validate
+ if (string.IsNullOrWhiteSpace(directoryPath))
+ throw new ArgumentNullException(nameof(directoryPath));
+ if (string.IsNullOrWhiteSpace(id))
+ throw new ArgumentNullException(nameof(id));
+ if (string.IsNullOrWhiteSpace(name))
+ throw new ArgumentNullException(nameof(name));
+ if (!Directory.Exists(directoryPath))
+ throw new ArgumentException($"Can't create content pack for directory path '{directoryPath}' because no such directory exists.");
+
+ // create manifest
+ IManifest manifest = new Manifest(
+ uniqueID: id,
+ name: name,
+ author: author,
+ description: description,
+ version: version,
+ contentPackFor: this.ModID
+ );
+
+ // create content pack
+ return this.CreateContentPack(directoryPath, manifest);
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/ModHelpers/ModHelper.cs b/src/SMAPI/Framework/ModHelpers/ModHelper.cs
index 070d9c65..ca872e32 100644
--- a/src/SMAPI/Framework/ModHelpers/ModHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/ModHelper.cs
@@ -13,21 +13,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
internal class ModHelper : BaseHelper, IModHelper, IDisposable
{
/*********
- ** Properties
- *********/
- /// <summary>The content packs loaded for this mod.</summary>
- private readonly Lazy<IContentPack[]> ContentPacks;
-
- /// <summary>Create a transitional content pack.</summary>
- private readonly Func<string, IManifest, IContentPack> CreateContentPack;
-
-#if !SMAPI_3_0_STRICT
- /// <summary>Manages deprecation warnings.</summary>
- private readonly DeprecationManager DeprecationManager;
-#endif
-
-
- /*********
** Accessors
*********/
/// <summary>The full path to the mod's folder.</summary>
@@ -44,6 +29,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>An API for loading content assets.</summary>
public IContentHelper Content { get; }
+ /// <summary>An API for managing content packs.</summary>
+ public IContentPackHelper ContentPacks { get; }
+
/// <summary>An API for reading and writing persistent mod data.</summary>
public IDataHelper Data { get; }
@@ -76,18 +64,16 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="inputState">Manages the game's input state.</param>
/// <param name="events">Manages access to events raised by SMAPI.</param>
/// <param name="contentHelper">An API for loading content assets.</param>
+ /// <param name="contentPackHelper">An API for managing content packs.</param>
/// <param name="commandHelper">An API for managing console commands.</param>
/// <param name="dataHelper">An API for reading and writing persistent mod data.</param>
/// <param name="modRegistry">an API for fetching metadata about loaded mods.</param>
/// <param name="reflectionHelper">An API for accessing private game code.</param>
/// <param name="multiplayer">Provides multiplayer utilities.</param>
/// <param name="translationHelper">An API for reading translations stored in the mod's <c>i18n</c> folder.</param>
- /// <param name="contentPacks">The content packs loaded for this mod.</param>
- /// <param name="createContentPack">Create a transitional content pack.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
/// <exception cref="ArgumentNullException">An argument is null or empty.</exception>
/// <exception cref="InvalidOperationException">The <paramref name="modDirectory"/> path does not exist on disk.</exception>
- public ModHelper(string modID, string modDirectory, JsonHelper jsonHelper, SInputState inputState, IModEvents events, IContentHelper contentHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper, Func<IContentPack[]> contentPacks, Func<string, IManifest, IContentPack> createContentPack, DeprecationManager deprecationManager)
+ public ModHelper(string modID, string modDirectory, JsonHelper jsonHelper, SInputState inputState, IModEvents events, IContentHelper contentHelper, IContentPackHelper contentPackHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper)
: base(modID)
{
// validate directory
@@ -99,6 +85,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
// initialise
this.DirectoryPath = modDirectory;
this.Content = contentHelper ?? throw new ArgumentNullException(nameof(contentHelper));
+ this.ContentPacks = contentPackHelper ?? throw new ArgumentNullException(nameof(contentPackHelper));
this.Data = dataHelper ?? throw new ArgumentNullException(nameof(dataHelper));
this.Input = new InputHelper(modID, inputState);
this.ModRegistry = modRegistry ?? throw new ArgumentNullException(nameof(modRegistry));
@@ -106,12 +93,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
this.Reflection = reflectionHelper ?? throw new ArgumentNullException(nameof(reflectionHelper));
this.Multiplayer = multiplayer ?? throw new ArgumentNullException(nameof(multiplayer));
this.Translation = translationHelper ?? throw new ArgumentNullException(nameof(translationHelper));
- this.ContentPacks = new Lazy<IContentPack[]>(contentPacks);
- this.CreateContentPack = createContentPack;
this.Events = events;
#if !SMAPI_3_0_STRICT
this.JsonHelper = jsonHelper ?? throw new ArgumentNullException(nameof(jsonHelper));
- this.DeprecationManager = deprecationManager;
#endif
}
@@ -171,39 +155,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
/****
** Content packs
****/
- /// <summary>Create a temporary content pack to read files from a directory. Temporary content packs will not appear in the SMAPI log and update checks will not be performed.</summary>
- /// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
- /// <param name="id">The content pack's unique ID.</param>
- /// <param name="name">The content pack name.</param>
- /// <param name="description">The content pack description.</param>
- /// <param name="author">The content pack author's name.</param>
- /// <param name="version">The content pack version.</param>
- public IContentPack CreateTemporaryContentPack(string directoryPath, string id, string name, string description, string author, ISemanticVersion version)
- {
- // validate
- if (string.IsNullOrWhiteSpace(directoryPath))
- throw new ArgumentNullException(nameof(directoryPath));
- if (string.IsNullOrWhiteSpace(id))
- throw new ArgumentNullException(nameof(id));
- if (string.IsNullOrWhiteSpace(name))
- throw new ArgumentNullException(nameof(name));
- if (!Directory.Exists(directoryPath))
- throw new ArgumentException($"Can't create content pack for directory path '{directoryPath}' because no such directory exists.");
-
- // create manifest
- IManifest manifest = new Manifest(
- uniqueID: id,
- name: name,
- author: author,
- description: description,
- version: version,
- contentPackFor: this.ModID
- );
-
- // create content pack
- return this.CreateContentPack(directoryPath, manifest);
- }
-
#if !SMAPI_3_0_STRICT
/// <summary>Manually create a transitional content pack to support pre-SMAPI content packs. This provides a way to access legacy content packs using the SMAPI content pack APIs, but the content pack will not be visible in the log or validated by SMAPI.</summary>
/// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
@@ -212,19 +163,20 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="description">The content pack description.</param>
/// <param name="author">The content pack author's name.</param>
/// <param name="version">The content pack version.</param>
- [Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.CreateTemporaryContentPack) + " instead")]
+ [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)
{
- this.DeprecationManager.Warn($"{nameof(IModHelper)}.{nameof(IModHelper.CreateTransitionalContentPack)}", "2.5", DeprecationLevel.Notice);
- return this.CreateTemporaryContentPack(directoryPath, id, name, description, author, version);
+ SCore.DeprecationManager.Warn($"{nameof(IModHelper)}.{nameof(IModHelper.CreateTransitionalContentPack)}", "2.5", DeprecationLevel.Notice);
+ return this.ContentPacks.CreateTemporary(directoryPath, id, name, description, author, version);
}
-#endif
/// <summary>Get all content packs loaded for this mod.</summary>
+ [Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ContentPacks) + "." + nameof(IContentPackHelper.GetOwned) + " instead")]
public IEnumerable<IContentPack> GetContentPacks()
{
- return this.ContentPacks.Value;
+ return this.ContentPacks.GetOwned();
}
+#endif
/****
** Disposal
diff --git a/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs b/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs
index 648d6742..cfe2ddbe 100644
--- a/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs
@@ -17,9 +17,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>The mod name for error messages.</summary>
private readonly string ModName;
- /// <summary>Manages deprecation warnings.</summary>
- private readonly DeprecationManager DeprecationManager;
-
/*********
** Public methods
@@ -28,13 +25,11 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="modName">The mod name for error messages.</param>
/// <param name="reflector">The underlying reflection helper.</param>
- /// <param name="deprecationManager">Manages deprecation warnings.</param>
- public ReflectionHelper(string modID, string modName, Reflector reflector, DeprecationManager deprecationManager)
+ public ReflectionHelper(string modID, string modName, Reflector reflector)
: base(modID)
{
this.ModName = modName;
this.Reflector = reflector;
- this.DeprecationManager = deprecationManager;
}
/// <summary>Get an instance field.</summary>
diff --git a/src/SMAPI/Framework/Networking/SGalaxyNetServer.cs b/src/SMAPI/Framework/Networking/SGalaxyNetServer.cs
index 2fc92737..82d11938 100644
--- a/src/SMAPI/Framework/Networking/SGalaxyNetServer.cs
+++ b/src/SMAPI/Framework/Networking/SGalaxyNetServer.cs
@@ -34,9 +34,14 @@ namespace StardewModdingAPI.Framework.Networking
this.OnProcessingMessage = onProcessingMessage;
}
+
+ /*********
+ ** Protected methods
+ *********/
/// <summary>Read and process a message from the client.</summary>
/// <param name="peer">The Galaxy peer ID.</param>
/// <param name="messageStream">The data to process.</param>
+ /// <remarks>This reimplements <see cref="GalaxyNetServer.onReceiveMessage"/>, but adds a callback to <see cref="OnProcessingMessage"/>.</remarks>
[SuppressMessage("ReSharper", "AccessToDisposedClosure", Justification = "The callback is invoked synchronously.")]
protected override void onReceiveMessage(GalaxyID peer, Stream messageStream)
{
@@ -44,20 +49,27 @@ namespace StardewModdingAPI.Framework.Networking
using (BinaryReader reader = new BinaryReader(messageStream))
{
message.Read(reader);
- this.OnProcessingMessage(message, outgoing => this.sendMessage(peer, outgoing), () =>
+ ulong peerID = peer.ToUint64(); // note: GalaxyID instances get reused, so need to store the underlying ID instead
+ this.OnProcessingMessage(message, outgoing => this.SendMessageToPeerID(peerID, outgoing), () =>
{
- if (this.peers.ContainsLeft(message.FarmerID) && (long)this.peers[message.FarmerID] == (long)peer.ToUint64())
- {
+ if (this.peers.ContainsLeft(message.FarmerID) && (long)this.peers[message.FarmerID] == (long)peerID)
this.gameServer.processIncomingMessage(message);
- }
else if (message.MessageType == StardewValley.Multiplayer.playerIntroduction)
{
NetFarmerRoot farmer = this.Multiplayer.readFarmer(message.Reader);
- GalaxyID capturedPeer = new GalaxyID(peer.ToUint64());
- this.gameServer.checkFarmhandRequest(Convert.ToString(peer.ToUint64()), farmer, msg => this.sendMessage(capturedPeer, msg), () => this.peers[farmer.Value.UniqueMultiplayerID] = capturedPeer.ToUint64());
+ GalaxyID capturedPeer = new GalaxyID(peerID);
+ this.gameServer.checkFarmhandRequest(Convert.ToString(peerID), farmer, msg => this.sendMessage(capturedPeer, msg), () => this.peers[farmer.Value.UniqueMultiplayerID] = capturedPeer.ToUint64());
}
});
}
}
+
+ /// <summary>Send a message to a remote peer.</summary>
+ /// <param name="peerID">The unique Galaxy ID, derived from <see cref="GalaxyID.ToUint64"/>.</param>
+ /// <param name="message">The message to send.</param>
+ private void SendMessageToPeerID(ulong peerID, OutgoingMessage message)
+ {
+ this.sendMessage(new GalaxyID(peerID), message);
+ }
}
}
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index 800b9c09..679838ba 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -75,10 +75,6 @@ namespace StardewModdingAPI.Framework
/// <remarks>This is initialised after the game starts.</remarks>
private readonly ModRegistry ModRegistry = new ModRegistry();
- /// <summary>Manages deprecation warnings.</summary>
- /// <remarks>This is initialised after the game starts.</remarks>
- private readonly DeprecationManager DeprecationManager;
-
/// <summary>Manages SMAPI events for mods.</summary>
private readonly EventManager EventManager;
@@ -121,6 +117,14 @@ namespace StardewModdingAPI.Framework
/*********
+ ** Accessors
+ *********/
+ /// <summary>Manages deprecation warnings.</summary>
+ /// <remarks>This is initialised after the game starts. This is accessed directly because it's not part of the normal class model.</remarks>
+ internal static DeprecationManager DeprecationManager { get; private set; }
+
+
+ /*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
@@ -148,15 +152,12 @@ namespace StardewModdingAPI.Framework
};
this.MonitorForGame = this.GetSecondaryMonitor("game");
this.EventManager = new EventManager(this.Monitor, this.ModRegistry);
- this.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry);
+ SCore.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry);
// redirect direct console output
if (this.MonitorForGame.WriteToConsole)
this.ConsoleManager.OnMessageIntercepted += message => this.HandleConsoleMessage(this.MonitorForGame, message);
- // inject deprecation managers
- SemanticVersion.DeprecationManager = this.DeprecationManager;
-
// init logging
this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info);
this.Monitor.Log($"Mods go here: {modsPath}");
@@ -183,7 +184,8 @@ namespace StardewModdingAPI.Framework
// apply game patches
new GamePatcher(this.Monitor).Apply(
- new DialogueErrorPatch(this.MonitorForGame, this.Reflection)
+ new DialogueErrorPatch(this.MonitorForGame, this.Reflection),
+ new ObjectErrorPatch()
);
}
@@ -196,19 +198,19 @@ namespace StardewModdingAPI.Framework
{
#if !SMAPI_3_0_STRICT
// hook up events
- ContentEvents.Init(this.EventManager, this.DeprecationManager);
- ControlEvents.Init(this.EventManager, this.DeprecationManager);
- GameEvents.Init(this.EventManager, this.DeprecationManager);
- GraphicsEvents.Init(this.EventManager, this.DeprecationManager);
- InputEvents.Init(this.EventManager, this.DeprecationManager);
- LocationEvents.Init(this.EventManager, this.DeprecationManager);
- MenuEvents.Init(this.EventManager, this.DeprecationManager);
- MineEvents.Init(this.EventManager, this.DeprecationManager);
- MultiplayerEvents.Init(this.EventManager, this.DeprecationManager);
- PlayerEvents.Init(this.EventManager, this.DeprecationManager);
- SaveEvents.Init(this.EventManager, this.DeprecationManager);
- SpecialisedEvents.Init(this.EventManager, this.DeprecationManager);
- TimeEvents.Init(this.EventManager, this.DeprecationManager);
+ ContentEvents.Init(this.EventManager);
+ ControlEvents.Init(this.EventManager);
+ GameEvents.Init(this.EventManager);
+ GraphicsEvents.Init(this.EventManager);
+ InputEvents.Init(this.EventManager);
+ LocationEvents.Init(this.EventManager);
+ MenuEvents.Init(this.EventManager);
+ MineEvents.Init(this.EventManager);
+ MultiplayerEvents.Init(this.EventManager);
+ PlayerEvents.Init(this.EventManager);
+ SaveEvents.Init(this.EventManager);
+ SpecialisedEvents.Init(this.EventManager);
+ TimeEvents.Init(this.EventManager);
#endif
// init JSON parser
@@ -232,7 +234,7 @@ namespace StardewModdingAPI.Framework
// override game
SGame.ConstructorHack = new SGameConstructorHack(this.Monitor, this.Reflection, this.Toolkit.JsonHelper);
- this.GameInstance = new SGame(this.Monitor, this.MonitorForGame, this.Reflection, this.EventManager, this.Toolkit.JsonHelper, this.ModRegistry, this.DeprecationManager, this.OnLocaleChanged, this.InitialiseAfterGameStart, this.Dispose);
+ this.GameInstance = new SGame(this.Monitor, this.MonitorForGame, this.Reflection, this.EventManager, this.Toolkit.JsonHelper, this.ModRegistry, SCore.DeprecationManager, this.OnLocaleChanged, this.InitialiseAfterGameStart, this.Dispose);
StardewValley.Program.gamePtr = this.GameInstance;
// add exit handler
@@ -312,9 +314,15 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log($"Technical details: {ex.GetLogSummary()}", LogLevel.Trace);
this.PressAnyKeyToExit();
}
+ catch (FileNotFoundException ex) when (ex.Message == "Could not find file 'C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Stardew Valley\\Content\\XACT\\FarmerSounds.xgs'.") // path in error is hardcoded regardless of install path
+ {
+ this.Monitor.Log("The game can't find its Content\\XACT\\FarmerSounds.xgs file. You can usually fix this by resetting your content files (see https://smapi.io/troubleshoot#reset-content ), or by uninstalling and reinstalling the game.", LogLevel.Error);
+ this.Monitor.Log($"Technical details: {ex.GetLogSummary()}", LogLevel.Trace);
+ this.PressAnyKeyToExit();
+ }
catch (Exception ex)
{
- this.Monitor.Log($"The game failed unexpectedly: {ex.GetLogSummary()}", LogLevel.Error);
+ this.MonitorForGame.Log($"The game failed to launch: {ex.GetLogSummary()}", LogLevel.Error);
this.PressAnyKeyToExit();
}
finally
@@ -920,7 +928,7 @@ namespace StardewModdingAPI.Framework
// add deprecation warning for old version format
{
if (mod.Manifest?.Version is Toolkit.SemanticVersion version && version.IsLegacyFormat)
- this.DeprecationManager.Warn(mod.DisplayName, "non-string manifest version", "2.8", DeprecationLevel.Notice);
+ SCore.DeprecationManager.Warn(mod.DisplayName, "non-string manifest version", "2.8", DeprecationLevel.Notice);
}
#endif
@@ -1014,20 +1022,21 @@ namespace StardewModdingAPI.Framework
IModEvents events = new ModEvents(mod, this.EventManager);
ICommandHelper commandHelper = new CommandHelper(mod, this.GameInstance.CommandManager);
IContentHelper contentHelper = new ContentHelper(contentCore, mod.DirectoryPath, manifest.UniqueID, mod.DisplayName, monitor);
+ IContentPackHelper contentPackHelper = new ContentPackHelper(manifest.UniqueID, new Lazy<IContentPack[]>(GetContentPacks), CreateFakeContentPack);
IDataHelper dataHelper = new DataHelper(manifest.UniqueID, mod.DirectoryPath, jsonHelper);
- IReflectionHelper reflectionHelper = new ReflectionHelper(manifest.UniqueID, mod.DisplayName, this.Reflection, this.DeprecationManager);
+ IReflectionHelper reflectionHelper = new ReflectionHelper(manifest.UniqueID, mod.DisplayName, this.Reflection);
IModRegistry modRegistryHelper = new ModRegistryHelper(manifest.UniqueID, this.ModRegistry, proxyFactory, monitor);
IMultiplayerHelper multiplayerHelper = new MultiplayerHelper(manifest.UniqueID, this.GameInstance.Multiplayer);
ITranslationHelper translationHelper = new TranslationHelper(manifest.UniqueID, manifest.Name, contentCore.GetLocale(), contentCore.Language);
- IContentPack CreateTransitionalContentPack(string packDirPath, IManifest packManifest)
+ IContentPack CreateFakeContentPack(string packDirPath, IManifest packManifest)
{
IMonitor packMonitor = this.GetSecondaryMonitor(packManifest.Name);
IContentHelper packContentHelper = new ContentHelper(contentCore, packDirPath, packManifest.UniqueID, packManifest.Name, packMonitor);
return new ContentPack(packDirPath, packManifest, packContentHelper, this.Toolkit.JsonHelper);
}
- modHelper = new ModHelper(manifest.UniqueID, mod.DirectoryPath, this.Toolkit.JsonHelper, this.GameInstance.Input, events, contentHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper, GetContentPacks, CreateTransitionalContentPack, this.DeprecationManager);
+ modHelper = new ModHelper(manifest.UniqueID, mod.DirectoryPath, this.Toolkit.JsonHelper, this.GameInstance.Input, events, contentHelper, contentPackHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper);
}
// init mod
diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs
index 7b3335b7..4d790d9f 100644
--- a/src/SMAPI/Framework/SGame.cs
+++ b/src/SMAPI/Framework/SGame.cs
@@ -1422,8 +1422,8 @@ namespace StardewModdingAPI.Framework
}
Game1.spriteBatch.End();
}
- this.Events.RenderedWorld.RaiseEmpty();
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null);
+ this.Events.RenderedWorld.RaiseEmpty();
if (Game1.drawGrid)
{
int num1 = -Game1.viewport.X % 64;
diff --git a/src/SMAPI/Framework/SMultiplayer.cs b/src/SMAPI/Framework/SMultiplayer.cs
index 12cd2d46..784edae3 100644
--- a/src/SMAPI/Framework/SMultiplayer.cs
+++ b/src/SMAPI/Framework/SMultiplayer.cs
@@ -119,6 +119,7 @@ namespace StardewModdingAPI.Framework
}
default:
+ this.Monitor.Log($"Unknown multiplayer client type: {client.GetType().AssemblyQualifiedName}", LogLevel.Trace);
return client;
}
}
@@ -142,6 +143,7 @@ namespace StardewModdingAPI.Framework
}
default:
+ this.Monitor.Log($"Unknown multiplayer server type: {server.GetType().AssemblyQualifiedName}", LogLevel.Trace);
return server;
}
}
diff --git a/src/SMAPI/IAssetDataForDictionary.cs b/src/SMAPI/IAssetDataForDictionary.cs
index 53c24346..911599d9 100644
--- a/src/SMAPI/IAssetDataForDictionary.cs
+++ b/src/SMAPI/IAssetDataForDictionary.cs
@@ -1,26 +1,32 @@
-using System;
+using System;
using System.Collections.Generic;
+using StardewModdingAPI.Framework.Content;
namespace StardewModdingAPI
{
/// <summary>Encapsulates access and changes to dictionary content being read from a data file.</summary>
public interface IAssetDataForDictionary<TKey, TValue> : IAssetData<IDictionary<TKey, TValue>>
{
+#if !SMAPI_3_0_STRICT
/*********
** Public methods
*********/
/// <summary>Add or replace an entry in the dictionary.</summary>
/// <param name="key">The entry key.</param>
/// <param name="value">The entry value.</param>
+ [Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")]
void Set(TKey key, TValue value);
/// <summary>Add or replace an entry in the dictionary.</summary>
/// <param name="key">The entry key.</param>
/// <param name="value">A callback which accepts the current value and returns the new value.</param>
+ [Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")]
void Set(TKey key, Func<TValue, TValue> value);
/// <summary>Dynamically replace values in the dictionary.</summary>
/// <param name="replacer">A lambda which takes the current key and value for an entry, and returns the new value.</param>
+ [Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")]
void Set(Func<TKey, TValue, TValue> replacer);
+#endif
}
}
diff --git a/src/SMAPI/ICommandHelper.cs b/src/SMAPI/ICommandHelper.cs
index fb562e32..196e1051 100644
--- a/src/SMAPI/ICommandHelper.cs
+++ b/src/SMAPI/ICommandHelper.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
namespace StardewModdingAPI
{
diff --git a/src/SMAPI/IContentPackHelper.cs b/src/SMAPI/IContentPackHelper.cs
new file mode 100644
index 00000000..e4949f58
--- /dev/null
+++ b/src/SMAPI/IContentPackHelper.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+
+namespace StardewModdingAPI
+{
+ /// <summary>Provides an API for managing content packs.</summary>
+ public interface IContentPackHelper : IModLinked
+ {
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Get all content packs loaded for this mod.</summary>
+ IEnumerable<IContentPack> GetOwned();
+
+ /// <summary>Create a temporary content pack to read files from a directory, using randomised manifest fields. Temporary content packs will not appear in the SMAPI log and update checks will not be performed.</summary>
+ /// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
+ IContentPack CreateFake(string directoryPath);
+
+ /// <summary>Create a temporary content pack to read files from a directory. Temporary content packs will not appear in the SMAPI log and update checks will not be performed.</summary>
+ /// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
+ /// <param name="id">The content pack's unique ID.</param>
+ /// <param name="name">The content pack name.</param>
+ /// <param name="description">The content pack description.</param>
+ /// <param name="author">The content pack author's name.</param>
+ /// <param name="version">The content pack version.</param>
+ IContentPack CreateTemporary(string directoryPath, string id, string name, string description, string author, ISemanticVersion version);
+ }
+}
diff --git a/src/SMAPI/IModHelper.cs b/src/SMAPI/IModHelper.cs
index fbe3d51f..0220b4f7 100644
--- a/src/SMAPI/IModHelper.cs
+++ b/src/SMAPI/IModHelper.cs
@@ -22,6 +22,9 @@ namespace StardewModdingAPI
/// <summary>An API for loading content assets.</summary>
IContentHelper Content { get; }
+ /// <summary>An API for managing content packs.</summary>
+ IContentPackHelper ContentPacks { get; }
+
/// <summary>An API for reading and writing persistent mod data.</summary>
IDataHelper Data { get; }
@@ -73,21 +76,10 @@ namespace StardewModdingAPI
/// <param name="model">The model to save.</param>
[Obsolete("Use " + nameof(IModHelper.Data) + "." + nameof(IDataHelper.WriteJsonFile) + " instead")]
void WriteJsonFile<TModel>(string path, TModel model) where TModel : class;
-#endif
/****
** Content packs
****/
- /// <summary>Create a temporary content pack to read files from a directory. Temporary content packs will not appear in the SMAPI log and update checks will not be performed.</summary>
- /// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
- /// <param name="id">The content pack's unique ID.</param>
- /// <param name="name">The content pack name.</param>
- /// <param name="description">The content pack description.</param>
- /// <param name="author">The content pack author's name.</param>
- /// <param name="version">The content pack version.</param>
- IContentPack CreateTemporaryContentPack(string directoryPath, string id, string name, string description, string author, ISemanticVersion version);
-
-#if !SMAPI_3_0_STRICT
/// <summary>Manually create a transitional content pack to support pre-SMAPI content packs. This provides a way to access legacy content packs using the SMAPI content pack APIs, but the content pack will not be visible in the log or validated by SMAPI.</summary>
/// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
/// <param name="id">The content pack's unique ID.</param>
@@ -95,11 +87,12 @@ namespace StardewModdingAPI
/// <param name="description">The content pack description.</param>
/// <param name="author">The content pack author's name.</param>
/// <param name="version">The content pack version.</param>
- [Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.CreateTemporaryContentPack) + " instead")]
+ [Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ContentPacks) + "." + nameof(IContentPackHelper.CreateTemporary) + " instead")]
IContentPack CreateTransitionalContentPack(string directoryPath, string id, string name, string description, string author, ISemanticVersion version);
-#endif
/// <summary>Get all content packs loaded for this mod.</summary>
+ [Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ContentPacks) + "." + nameof(IContentPackHelper.GetOwned) + " instead")]
IEnumerable<IContentPack> GetContentPacks();
+#endif
}
}
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 90629d7f..a44ab7d1 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -31,6 +31,9 @@ namespace StardewModdingAPI.Metadata
/// <summary>Simplifies access to private game code.</summary>
private readonly Reflector Reflection;
+ /// <summary>Encapsulates monitoring and logging.</summary>
+ private readonly IMonitor Monitor;
+
/*********
** Public methods
@@ -38,10 +41,12 @@ namespace StardewModdingAPI.Metadata
/// <summary>Initialise the core asset data.</summary>
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
/// <param name="reflection">Simplifies access to private code.</param>
- public CoreAssetPropagator(Func<string, string> getNormalisedPath, Reflector reflection)
+ /// <param name="monitor">Encapsulates monitoring and logging.</param>
+ public CoreAssetPropagator(Func<string, string> getNormalisedPath, Reflector reflection, IMonitor monitor)
{
this.GetNormalisedPath = getNormalisedPath;
this.Reflection = reflection;
+ this.Monitor = monitor;
}
/// <summary>Reload one of the game's core assets (if applicable).</summary>
@@ -499,7 +504,7 @@ namespace StardewModdingAPI.Metadata
if (!character.isVillager() || !dispositions.ContainsKey(character.Name))
continue;
- NPC clone = new NPC(null, Vector2.Zero, 0, character.Name);
+ NPC clone = new NPC(null, character.Position, character.DefaultMap, character.FacingDirection, character.Name, null, character.Portrait, eventActor: false);
character.Age = clone.Age;
character.Manners = clone.Manners;
character.SocialAnxiety = clone.SocialAnxiety;
@@ -619,6 +624,11 @@ namespace StardewModdingAPI.Metadata
{
// reload schedule
villager.Schedule = villager.getSchedule(Game1.dayOfMonth);
+ if (villager.Schedule == null)
+ {
+ this.Monitor.Log($"A mod set an invalid schedule for {villager.Name ?? key}, so the NPC may not behave correctly.", LogLevel.Warn);
+ return true;
+ }
// switch to new schedule if needed
int lastScheduleTime = villager.Schedule.Keys.Where(p => p <= Game1.timeOfDay).OrderByDescending(p => p).FirstOrDefault();
diff --git a/src/SMAPI/Patches/ObjectErrorPatch.cs b/src/SMAPI/Patches/ObjectErrorPatch.cs
new file mode 100644
index 00000000..2cbb60c5
--- /dev/null
+++ b/src/SMAPI/Patches/ObjectErrorPatch.cs
@@ -0,0 +1,55 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using Harmony;
+using StardewModdingAPI.Framework.Patching;
+using StardewValley;
+using SObject = StardewValley.Object;
+
+namespace StardewModdingAPI.Patches
+{
+ /// <summary>A Harmony patch for <see cref="SObject.getDescription"/> which intercepts crashes due to the item no longer existing.</summary>
+ internal class ObjectErrorPatch : IHarmonyPatch
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>A unique name for this patch.</summary>
+ public string Name => $"{nameof(ObjectErrorPatch)}";
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Apply the Harmony patch.</summary>
+ /// <param name="harmony">The Harmony instance.</param>
+ public void Apply(HarmonyInstance harmony)
+ {
+ MethodInfo method = AccessTools.Method(typeof(SObject), nameof(SObject.getDescription));
+ MethodInfo prefix = AccessTools.Method(this.GetType(), nameof(ObjectErrorPatch.Prefix));
+
+ harmony.Patch(method, new HarmonyMethod(prefix), null);
+ }
+
+
+ /*********
+ ** Private methods
+ *********/
+ /// <summary>The method to call instead of <see cref="StardewValley.Object.getDescription"/>.</summary>
+ /// <param name="__instance">The instance being patched.</param>
+ /// <param name="__result">The patched method's return value.</param>
+ /// <returns>Returns whether to execute the original method.</returns>
+ /// <remarks>This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments.</remarks>
+ [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Argument names are defined by Harmony.")]
+ private static bool Prefix(SObject __instance, ref string __result)
+ {
+ // invalid bigcraftables crash instead of showing '???' like invalid non-bigcraftables
+ if (!__instance.IsRecipe && __instance.bigCraftable.Value && !Game1.bigCraftablesInformation.ContainsKey(__instance.ParentSheetIndex))
+ {
+ __result = "???";
+ return false;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/SMAPI/SemanticVersion.cs b/src/SMAPI/SemanticVersion.cs
index f75105df..4fc6c219 100644
--- a/src/SMAPI/SemanticVersion.cs
+++ b/src/SMAPI/SemanticVersion.cs
@@ -13,9 +13,6 @@ namespace StardewModdingAPI
/// <summary>The underlying semantic version implementation.</summary>
private readonly ISemanticVersion Version;
- /// <summary>Manages deprecation warnings.</summary>
- internal static DeprecationManager DeprecationManager { get; set; }
-
/*********
** Accessors
@@ -36,7 +33,7 @@ namespace StardewModdingAPI
{
get
{
- SemanticVersion.DeprecationManager?.Warn($"{nameof(ISemanticVersion)}.{nameof(ISemanticVersion.Build)}", "2.8", DeprecationLevel.Notice);
+ SCore.DeprecationManager?.Warn($"{nameof(ISemanticVersion)}.{nameof(ISemanticVersion.Build)}", "2.8", DeprecationLevel.Notice);
return this.Version.PrereleaseTag;
}
}
diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj
index 49a88f37..9b00e777 100644
--- a/src/SMAPI/StardewModdingAPI.csproj
+++ b/src/SMAPI/StardewModdingAPI.csproj
@@ -32,7 +32,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
- <DefineConstants>DEBUG;TRACE;SMAPI_3_0_STRICT</DefineConstants>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
<UseVSHostingProcess>true</UseVSHostingProcess>
<Optimize>false</Optimize>
<OutputPath>$(SolutionDir)\..\bin\Debug\SMAPI</OutputPath>
@@ -174,6 +174,7 @@
<Compile Include="Framework\Events\ModPlayerEvents.cs" />
<Compile Include="Framework\Events\ModSpecialisedEvents.cs" />
<Compile Include="Framework\Events\ModWorldEvents.cs" />
+ <Compile Include="Framework\ModHelpers\ContentPackHelper.cs" />
<Compile Include="Framework\ModHelpers\DataHelper.cs" />
<Compile Include="Framework\Networking\MessageType.cs" />
<Compile Include="Framework\Networking\ModMessageModel.cs" />
@@ -207,6 +208,7 @@
<Compile Include="Framework\StateTracking\Comparers\GenericEqualsComparer.cs" />
<Compile Include="Framework\StateTracking\FieldWatchers\ComparableListWatcher.cs" />
<Compile Include="Framework\WatcherCore.cs" />
+ <Compile Include="IContentPackHelper.cs" />
<Compile Include="IDataHelper.cs" />
<Compile Include="IInputHelper.cs" />
<Compile Include="Framework\Input\SInputState.cs" />
@@ -324,6 +326,7 @@
<Compile Include="Framework\Monitor.cs" />
<Compile Include="Metadata\InstructionMetadata.cs" />
<Compile Include="Mod.cs" />
+ <Compile Include="Patches\ObjectErrorPatch.cs" />
<Compile Include="Patches\DialogueErrorPatch.cs" />
<Compile Include="PatchMode.cs" />
<Compile Include="GamePlatform.cs" />
diff --git a/src/StardewModdingAPI.Toolkit.CoreInterfaces/StardewModdingAPI.Toolkit.CoreInterfaces.csproj b/src/StardewModdingAPI.Toolkit.CoreInterfaces/StardewModdingAPI.Toolkit.CoreInterfaces.csproj
index 539cb5d8..525931e5 100644
--- a/src/StardewModdingAPI.Toolkit.CoreInterfaces/StardewModdingAPI.Toolkit.CoreInterfaces.csproj
+++ b/src/StardewModdingAPI.Toolkit.CoreInterfaces/StardewModdingAPI.Toolkit.CoreInterfaces.csproj
@@ -8,10 +8,6 @@
<DocumentationFile>..\..\bin\$(Configuration)\SMAPI.Toolkit.CoreInterfaces\$(TargetFramework)\StardewModdingAPI.Toolkit.CoreInterfaces.xml</DocumentationFile>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)'=='Debug'">
- <DefineConstants>$(DefineConstants);SMAPI_3_0_STRICT</DefineConstants>
- </PropertyGroup>
-
<ItemGroup>
<Compile Include="..\..\build\GlobalAssemblyInfo.cs" Link="Properties\GlobalAssemblyInfo.cs" />
</ItemGroup>
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModExtendedMetadataModel.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModExtendedMetadataModel.cs
index c9d9f916..45b46ea6 100644
--- a/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModExtendedMetadataModel.cs
+++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModExtendedMetadataModel.cs
@@ -41,6 +41,15 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
public string CustomUrl { get; set; }
/****
+ ** SMAPI 3.0 readiness
+ ****/
+ /// <summary>Whether the mod is ready for the upcoming SMAPI 3.0.</summary>
+ public WikiSmapi3Status Smapi3Status { get; set; }
+
+ /// <summary>A URL related to the <see cref="Smapi3Status"/>.</summary>
+ public string Smapi3Url { get; set; }
+
+ /****
** Stable compatibility
****/
/// <summary>The compatibility status.</summary>
@@ -85,6 +94,9 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
this.CustomSourceUrl = wiki.CustomSourceUrl;
this.CustomUrl = wiki.CustomUrl;
+ this.Smapi3Status = wiki.Smapi3Status;
+ this.Smapi3Url = wiki.Smapi3Url;
+
this.CompatibilityStatus = wiki.Compatibility.Status;
this.CompatibilitySummary = wiki.Compatibility.Summary;
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs
index 91078b08..19a4292f 100644
--- a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs
+++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs
@@ -102,7 +102,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
// parse stable compatibility
WikiCompatibilityInfo compatibility = new WikiCompatibilityInfo
{
- Status = this.GetAttributeAsStatus(node, "data-status") ?? WikiCompatibilityStatus.Ok,
+ Status = this.GetAttributeAsEnum<WikiCompatibilityStatus>(node, "data-status") ?? WikiCompatibilityStatus.Ok,
BrokeIn = this.GetAttribute(node, "data-broke-in"),
UnofficialVersion = this.GetAttributeAsSemanticVersion(node, "data-unofficial-version"),
UnofficialUrl = this.GetAttribute(node, "data-unofficial-url"),
@@ -112,7 +112,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
// parse beta compatibility
WikiCompatibilityInfo betaCompatibility = null;
{
- WikiCompatibilityStatus? betaStatus = this.GetAttributeAsStatus(node, "data-beta-status");
+ WikiCompatibilityStatus? betaStatus = this.GetAttributeAsEnum<WikiCompatibilityStatus>(node, "data-beta-status");
if (betaStatus.HasValue)
{
betaCompatibility = new WikiCompatibilityInfo
@@ -126,6 +126,10 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
}
}
+ // parse SMAPI 3.0 readiness status
+ WikiSmapi3Status smapi3Status = this.GetAttributeAsEnum<WikiSmapi3Status>(node, "data-smapi-3-status") ?? WikiSmapi3Status.Unknown;
+ string smapi3Url = this.GetAttribute(node, "data-smapi-3-url");
+
// yield model
yield return new WikiModEntry
{
@@ -140,6 +144,8 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
CustomUrl = customUrl,
Compatibility = compatibility,
BetaCompatibility = betaCompatibility,
+ Smapi3Status = smapi3Status,
+ Smapi3Url = smapi3Url,
Warnings = warnings,
Anchor = anchor
};
@@ -169,17 +175,18 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
: new string[0];
}
- /// <summary>Get an attribute value and parse it as a compatibility status.</summary>
+ /// <summary>Get an attribute value and parse it as an enum value.</summary>
+ /// <typeparam name="TEnum">The enum type.</typeparam>
/// <param name="element">The element whose attributes to read.</param>
/// <param name="name">The attribute name.</param>
- private WikiCompatibilityStatus? GetAttributeAsStatus(HtmlNode element, string name)
+ private TEnum? GetAttributeAsEnum<TEnum>(HtmlNode element, string name) where TEnum : struct
{
string raw = this.GetAttribute(element, name);
if (raw == null)
return null;
- if (!Enum.TryParse(raw, true, out WikiCompatibilityStatus status))
- throw new InvalidOperationException($"Unknown status '{raw}' when parsing compatibility list.");
- return status;
+ if (!Enum.TryParse(raw, true, out TEnum value) && Enum.IsDefined(typeof(TEnum), value))
+ throw new InvalidOperationException($"Unknown {typeof(TEnum).Name} value '{raw}' when parsing compatibility list.");
+ return value;
}
/// <summary>Get an attribute value and parse it as a semantic version.</summary>
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs
index f7b7839b..b71269fe 100644
--- a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs
+++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs
@@ -39,6 +39,12 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
/// <summary>The mod's compatibility with the latest beta version of the game (if any).</summary>
public WikiCompatibilityInfo BetaCompatibility { get; set; }
+ /// <summary>Whether the mod is ready for the upcoming SMAPI 3.0.</summary>
+ public WikiSmapi3Status Smapi3Status { get; set; }
+
+ /// <summary>A URL related to the <see cref="Smapi3Status"/>.</summary>
+ public string Smapi3Url { get; set; }
+
/// <summary>Whether a Stardew Valley or SMAPI beta which affects mod compatibility is in progress. If this is true, <see cref="BetaCompatibility"/> should be used for beta versions of SMAPI instead of <see cref="Compatibility"/>.</summary>
public bool HasBetaInfo => this.BetaCompatibility != null;
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiSmapi3Status.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiSmapi3Status.cs
new file mode 100644
index 00000000..879cfd8a
--- /dev/null
+++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiSmapi3Status.cs
@@ -0,0 +1,18 @@
+namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
+{
+ /// <summary>Whether a mod is ready for the upcoming SMAPI 3.0.</summary>
+ public enum WikiSmapi3Status
+ {
+ /// <summary>The mod's compatibility status is unknown.</summary>
+ Unknown = 0,
+
+ /// <summary>The mod is compatible with the upcoming SMAPI 3.0.</summary>
+ Ok = 1,
+
+ /// <summary>The mod will break in SMAPI 3.0.</summary>
+ Broken = 2,
+
+ /// <summary>The mod has a pull request submitted for SMAPI 3.0 compatibility.</summary>
+ Soon = 3
+ }
+}
diff --git a/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj b/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj
index 29667b1e..3fa28d19 100644
--- a/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj
+++ b/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj
@@ -7,10 +7,6 @@
<DocumentationFile>..\..\bin\$(Configuration)\SMAPI.Toolkit\$(TargetFramework)\StardewModdingAPI.Toolkit.xml</DocumentationFile>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)'=='Debug'">
- <DefineConstants>$(DefineConstants);SMAPI_3_0_STRICT</DefineConstants>
- </PropertyGroup>
-
<ItemGroup>
<Compile Include="..\..\build\GlobalAssemblyInfo.cs" Link="Properties\GlobalAssemblyInfo.cs" />
</ItemGroup>