TerrariaHooks should be generated from tModLoader, rather than vanilla
See original GitHub issueAs far as I can tell by looking at the code for the setup tool, right now the TerrariaHooks.dll
included in tModLoader is generated from the vanilla version of Terraria.exe
.
This can lead to problems with methods, who’s signature is changed by tModLoader. For Instance:
The generated “On” hook looks like this:
.event On.Terraria.Chest/hook_AddShop AddShop
{
.addon void On.Terraria.Chest::add_AddShop(class On.Terraria.Chest/hook_AddShop)
.removeon void On.Terraria.Chest::remove_AddShop(class On.Terraria.Chest/hook_AddShop)
}
.method public hidebysig specialname static
void add_AddShop (
class On.Terraria.Chest/hook_AddShop ''
) cil managed
{
// Header Size: 1 byte
// Code Size: 17 (0x11) bytes
.maxstack 8
/* 0x0002C615 D0E509000A */ IL_0000: ldtoken method instance void [Terraria]Terraria.Chest::AddShop(class [Terraria]Terraria.Item)
/* 0x0002C61A 280200000A */ IL_0005: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
/* 0x0002C61F 02 */ IL_000A: ldarg.0
/* 0x0002C620 285327002B */ IL_000B: call void [MonoMod.RuntimeDetour]MonoMod.RuntimeDetour.HookGen.HookEndpointManager::Add<class On.Terraria.Chest/hook_AddShop>(class [mscorlib]System.Reflection.MethodBase, class [mscorlib]System.Delegate)
/* 0x0002C625 2A */ IL_0010: ret
} // end of method Chest::add_AddShop
.method public hidebysig specialname static
void remove_AddShop (
class On.Terraria.Chest/hook_AddShop ''
) cil managed
{
// Header Size: 1 byte
// Code Size: 17 (0x11) bytes
.maxstack 8
/* 0x0002C627 D0E509000A */ IL_0000: ldtoken method instance void [Terraria]Terraria.Chest::AddShop(class [Terraria]Terraria.Item)
/* 0x0002C62C 280200000A */ IL_0005: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
/* 0x0002C631 02 */ IL_000A: ldarg.0
/* 0x0002C632 285427002B */ IL_000B: call void [MonoMod.RuntimeDetour]MonoMod.RuntimeDetour.HookGen.HookEndpointManager::Remove<class On.Terraria.Chest/hook_AddShop>(class [mscorlib]System.Reflection.MethodBase, class [mscorlib]System.Delegate)
/* 0x0002C637 2A */ IL_0010: ret
} // end of method Chest::remove_AddShop
Trying to use this will immediately trigger a System.MissingMethodException
, since method instance void [Terraria]Terraria.Chest::AddShop(class [Terraria]Terraria.Item)
does not actually exist anymore.
I’m not entirely sure how many methods this actually affects. There might not be too many, but it would be nice to have this sorted out.
I’m guessing hooks are generated this way to stop hooks from being made for internal tModLoader stuff? If that is the case, it shouldn’t be too hard to just modify HookGen to ignore certain namespaces.
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (4 by maintainers)
If the HookGen was set up to ignore tModLoader specific namespaces, it would only need to be run when a vanilla method got changed. Which I’d imagine does not happen too frequently.
As for the automatic approach, It might be possible to create the hooks during the build, with something like Fody.
Done be2c20251757ce5bf956d3853ebfafbe3e419eb6