summaryrefslogtreecommitdiff
path: root/src/SMAPI
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI')
-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
33 files changed, 339 insertions, 253 deletions
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" />