SMAPI - Stardew Modding API

SMAPI - Stardew Modding API

971k Downloads

Rewrite references to `StardewModdingAPI.Inheritance.ItemStackChange`

Pathoschild opened this issue ยท 2 comments

commented

SMAPI 1.9 beta moves StardewModdingAPI.Inheritance.ItemStackChange to StardewModdingAPI.Events.ItemStackChange where it belongs, but it doesn't have a CIL rewriter to fix mods that reference the old namespace yet. (See Constants::GetRewriters and Game1_GameMode_FieldRewriter for some example rewriters.)

commented

I have a new TypeReferenceRewriter that seems to be rewriting all the instructions, though it doesn't quite work yet (see changes so far).

For example, Casks Anywhere only references ItemStackChange in this method (via e.Removed):

void OnInventoryChanged(object sender, EventArgsInventoryChanged e)
{
   foreach (var item in e.Removed)
   {
      // ensure this is a cask
      if (item.Item.Name != "Cask")
         continue;
      
      // hijack the cask
      Hijack();
   }
}

This log shows the CIL instructions SMAPI is rewriting:

Rewriting CasksAnywhere to fix StardewModdingAPI.Inheritance.ItemStackChange type...
#########################
## Was: IL_0003: callvirt System.Collections.Generic.List`1<StardewModdingAPI.Inheritance.ItemStackChange> StardewModdingAPI.Events.EventArgsInventoryChanged::get_Removed()
## Now: IL_0003: callvirt System.Collections.Generic.List`1<StardewModdingAPI.Events.ItemStackChange> StardewModdingAPI.Events.EventArgsInventoryChanged::get_Removed()
#########################
## Was: IL_0008: callvirt System.Collections.Generic.List`1/Enumerator<!0> System.Collections.Generic.List`1<StardewModdingAPI.Inheritance.ItemStackChange>::GetEnumerator()
## Now: IL_0008: callvirt System.Collections.Generic.List`1/Enumerator<!0> System.Collections.Generic.List`1<StardewModdingAPI.Events.ItemStackChange>::GetEnumerator()
#########################
## Was: IL_0015: call !0 System.Collections.Generic.List`1/Enumerator<StardewModdingAPI.Inheritance.ItemStackChange>::get_Current()
## Now: IL_0015: call !0 System.Collections.Generic.List`1/Enumerator<StardewModdingAPI.Events.ItemStackChange>::get_Current()
#########################
## Was: IL_001d: callvirt StardewValley.Item StardewModdingAPI.Inheritance.ItemStackChange::get_Item()
## Now: IL_001d: callvirt StardewValley.Item StardewModdingAPI.Events.ItemStackChange::get_Item()
#########################
## Was: IL_0044: call System.Boolean System.Collections.Generic.List`1/Enumerator<StardewModdingAPI.Inheritance.ItemStackChange>::MoveNext()
## Now: IL_0044: call System.Boolean System.Collections.Generic.List`1/Enumerator<StardewModdingAPI.Events.ItemStackChange>::MoveNext()
#########################
## Was: IL_0055: constrained. System.Collections.Generic.List`1/Enumerator<StardewModdingAPI.Inheritance.ItemStackChange>
## Now: IL_0055: constrained. System.Collections.Generic.List`1/Enumerator<StardewModdingAPI.Events.ItemStackChange>
#########################

The mod still crashes when that code gets invoked, though:

[23:55:03 ERROR SMAPI] A mod failed handling the PlayerEvents.InventoryChanged event:
Failed loading type: StardewModdingAPI.Inheritance.ItemStackChange: System.TypeLoadException: Could not load type 'StardewModdingAPI.Inheritance.ItemStackChange' from assembly 'StardewModdingAPI, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null'.
   at CasksAnywhere.CasksAnywhere.OnInventoryChanged(Object sender, EventArgsInventoryChanged e)
   at StardewModdingAPI.Framework.InternalExtensions.SafelyRaiseGenericEvent[TEventArgs](IMonitor monitor, String name, IEnumerable`1 handlers, Object sender, TEventArgs args) in D:\source\_Stardew\SMAPI\src\StardewModdingAPI\Framework\InternalExtensions.cs:line 71
commented

Done in develop for the upcoming SMAPI 1.9 release.