From 6b1aca8efad6d4211db06a79b1f228be911ecb7b Mon Sep 17 00:00:00 2001 From: zhurengong <2731412072@qq.com> Date: Wed, 10 Nov 2021 21:07:19 +0800 Subject: [PATCH 1/2] modified way to patch, can realize params map for compatibility, and try to hook Item in lua. --- .../BarotraumaShared/Lua/DefaultHook.lua | 10 ++ .../BarotraumaShared/Lua/DefaultLib.lua | 2 +- Barotrauma/BarotraumaShared/Lua/LuaSetup.lua | 2 + .../SharedSource/Items/Item.cs | 41 ------ .../SharedSource/Lua/LuaClasses.cs | 117 +++++++++--------- 5 files changed, 72 insertions(+), 100 deletions(-) create mode 100644 Barotrauma/BarotraumaShared/Lua/DefaultHook.lua diff --git a/Barotrauma/BarotraumaShared/Lua/DefaultHook.lua b/Barotrauma/BarotraumaShared/Lua/DefaultHook.lua new file mode 100644 index 000000000..40bfc8b70 --- /dev/null +++ b/Barotrauma/BarotraumaShared/Lua/DefaultHook.lua @@ -0,0 +1,10 @@ + +Hook.HookMethod("Barotrauma.Item", "TryInteract", "itemInteract", nil) -- instance, picker, ignoreRequiredItems, forceSelectKey, forceActionKey +Hook.HookMethod("Barotrauma.Item", "Use", "itemUse", function (instance, deltaTime, character, targetLimb) return {instance, character, targetLimb} end) +Hook.HookMethod("Barotrauma.Item", "SecondaryUse", "itemSecondaryUse", function (instance, deltaTime, character) return {instance, character} end) +Hook.HookMethod("Barotrauma.Item", "ApplyTreatment", "itemApplyTreatment", nil) -- instance, user, character, targetLimb +Hook.HookMethod("Barotrauma.Item", "Combine", "itemCombine", nil) -- instance, item, user +Hook.HookMethod("Barotrauma.Item", "Drop", "itemDrop", function (instance, dropper, createNetworkEvent) return {instance, dropper} end) +Hook.HookMethod("Barotrauma.Item", "Equip", "itemEquip", nil) -- instance, character +Hook.HookMethod("Barotrauma.Item", "Unequip", "itemUnequip", nil) -- instance, character + diff --git a/Barotrauma/BarotraumaShared/Lua/DefaultLib.lua b/Barotrauma/BarotraumaShared/Lua/DefaultLib.lua index 9f74e2163..19a764ffe 100644 --- a/Barotrauma/BarotraumaShared/Lua/DefaultLib.lua +++ b/Barotrauma/BarotraumaShared/Lua/DefaultLib.lua @@ -49,7 +49,7 @@ if SERVER then elseif CLIENT then defaultLib["Sprite"] = CreateStatic("Sprite") - defaultLib["Keys"] = LuaUserData.RegisterType("Microsoft.Xna.Framework.Input.Keys") + defaultLib["Keys"] = LuaUserData.CreateStatic("Microsoft.Xna.Framework.Input.Keys") defaultLib["PlayerInput"] = CreateStatic("PlayerInput") end diff --git a/Barotrauma/BarotraumaShared/Lua/LuaSetup.lua b/Barotrauma/BarotraumaShared/Lua/LuaSetup.lua index cd058681c..b9640b786 100644 --- a/Barotrauma/BarotraumaShared/Lua/LuaSetup.lua +++ b/Barotrauma/BarotraumaShared/Lua/LuaSetup.lua @@ -11,6 +11,8 @@ for key, value in pairs(defaultLib) do _G[key] = value end +require("DefaultHook") + -- Execute Mods if SERVER and Game.IsDedicated then diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs index 8ddd1506a..d1d17d44b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs @@ -2166,11 +2166,6 @@ namespace Barotrauma public bool TryInteract(Character picker, bool ignoreRequiredItems = false, bool forceSelectKey = false, bool forceActionKey = false) { - var should = new LuaResult(GameMain.Lua.hook.Call("itemInteract", new object[] { this, picker, ignoreRequiredItems, forceSelectKey, forceActionKey })); - - if (!should.IsNull()) - return should.Bool(); - if (CampaignInteractionType != CampaignMode.InteractionType.None) { return false; } bool picked = false, selected = false; @@ -2309,11 +2304,6 @@ namespace Barotrauma if (condition == 0.0f) { return; } - var should = new LuaResult(GameMain.Lua.hook.Call("itemUse", new object[] { this, character, targetLimb })); - - if (should.Bool()) - return; - bool remove = false; foreach (ItemComponent ic in components) @@ -2347,12 +2337,6 @@ namespace Barotrauma { if (condition == 0.0f) { return; } - var should = new LuaResult(GameMain.Lua.hook.Call("itemSecondaryUse", new object[] { this, character})); - - if (should.Bool()) - return; - - bool remove = false; foreach (ItemComponent ic in components) @@ -2384,11 +2368,6 @@ namespace Barotrauma public void ApplyTreatment(Character user, Character character, Limb targetLimb) { - var should = new LuaResult(GameMain.Lua.hook.Call("itemApplyTreatment", new object[] { this, user, character, targetLimb })); - - if (should.Bool()) - return; - //can't apply treatment to dead characters if (character.IsDead) { return; } if (!UseInHealthInterface) { return; } @@ -2454,11 +2433,6 @@ namespace Barotrauma public bool Combine(Item item, Character user) { - var should = new LuaResult(GameMain.Lua.hook.Call("itemCombine", new object[] { this, item, user })); - - if (!should.IsNull()) - return should.Bool(); - if (item == this) { return false; } bool isCombined = false; foreach (ItemComponent ic in components) @@ -2473,11 +2447,6 @@ namespace Barotrauma public void Drop(Character dropper, bool createNetworkEvent = true) { - var should = new LuaResult(GameMain.Lua.hook.Call("itemDrop", new object[] { this, dropper})); - - if (should.Bool()) - return; - if (createNetworkEvent) { if (parentInventory != null && !parentInventory.Owner.Removed && !Removed && @@ -2530,11 +2499,6 @@ namespace Barotrauma public void Equip(Character character) { - var should = new LuaResult(GameMain.Lua.hook.Call("itemEquip", new object[] { this, character})); - - if (should.Bool()) - return; - if (Removed) { DebugConsole.ThrowError($"Tried to equip a removed item ({Name}).\n{Environment.StackTrace.CleanupStackTrace()}"); @@ -2546,11 +2510,6 @@ namespace Barotrauma public void Unequip(Character character) { - var should = new LuaResult(GameMain.Lua.hook.Call("itemUnequip", new object[] { this, character })); - - if (should.Bool()) - return; - foreach (ItemComponent ic in components) { ic.Unequip(character); } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs index 88c980a46..44148123f 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs @@ -77,12 +77,12 @@ namespace Barotrauma descriptor.AddMetaMember("__call", new ObjectCallbackMemberDescriptor("__call", LuaSetup.luaSetup.HandleCall)); } - public static void MakeFieldAccessible(IUserDataDescriptor IUUD, string methodName) + public static void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName) { var descriptor = (StandardUserDataDescriptor)IUUD; - var field = IUUD.Type.GetField(methodName, BindingFlags.NonPublic | BindingFlags.Instance); - descriptor.RemoveMember(methodName); - descriptor.AddMember(methodName, new FieldMemberDescriptor(field, InteropAccessMode.Default)); + var field = IUUD.Type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + descriptor.RemoveMember(fieldName); + descriptor.AddMember(fieldName, new FieldMemberDescriptor(field, InteropAccessMode.Default)); } public static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName) @@ -712,7 +712,8 @@ namespace Barotrauma public LuaHook(LuaSetup e) { env = e; - methodNameToHookName = new Dictionary(); + _methodPathToHookName = new Dictionary(); + _luaPatchParamsMap = new Dictionary(); } public class HookFunction @@ -731,7 +732,8 @@ namespace Barotrauma private Dictionary> hookFunctions = new Dictionary>(); - private static Dictionary methodNameToHookName; + private static Dictionary _methodPathToHookName; + private static Dictionary _luaPatchParamsMap; private Queue> queuedFunctionCalls = new Queue>(); @@ -740,47 +742,48 @@ namespace Barotrauma Before, After } - static bool HookLuaPatchPrefix(MethodBase __originalMethod, object[] __params, object __instance) + static void _hookLuaPatchPreProcess(MethodBase __originalMethod, object[] __params, object __instance, out string hookName, out object[] parameters) { - object[] parameters; + try + { + var @class = __originalMethod.DeclaringType; + var methodPath = $"{@class.Namespace}.{@class.Name}.{__originalMethod.Name}"; - if (__instance == null) - { - parameters = __params; - } - else - { + hookName = _methodPathToHookName[methodPath]; + + // Regardless of whether __instance is null or not, it's necessaray to avoid the inability to distinguish parameters when adding hooks in lua. parameters = new object[__params.Length + 1]; __params.CopyTo(parameters, 1); parameters[0] = __instance; + // Map the parameters for compatibility + if (_luaPatchParamsMap.TryGetValue(methodPath, out object map)) + { + var result = luaSetup.hook.env.lua.Call(map, parameters); + if (!result.IsNil()) parameters = result.ToObject(); + } + } - - var result = new LuaResult(luaSetup.hook.Call(methodNameToHookName[__originalMethod.Name], parameters)); - - if (!result.IsNull()) + catch (Exception ex) { - return false; + parameters = null; + hookName = null; + DebugConsole.ThrowError(nameof(_hookLuaPatchPreProcess), ex); } + } - return true; + static bool HookLuaPatchPrefix(MethodBase __originalMethod, object[] __params, object __instance) + { + _hookLuaPatchPreProcess(__originalMethod, __params, __instance, out string hookName, out object[] parameters); + + var result = new LuaResult(luaSetup.hook.Call(hookName, parameters)); + return result.IsNull(); } static bool HookLuaPatchRetPrefix(MethodBase __originalMethod, object[] __params, ref object __result, object __instance) { - object[] parameters; + _hookLuaPatchPreProcess(__originalMethod, __params, __instance, out string hookName, out object[] parameters); - if (__instance == null) - { - parameters = __params; - } - else - { - parameters = new object[__params.Length + 1]; - __params.CopyTo(parameters, 1); - parameters[0] = __instance; - } - - var result = new LuaResult(luaSetup.hook.Call(methodNameToHookName[__originalMethod.Name], parameters)); + var result = new LuaResult(luaSetup.hook.Call(hookName, parameters)); if (!result.IsNull()) { @@ -793,37 +796,26 @@ namespace Barotrauma static void HookLuaPatchPostfix(MethodBase __originalMethod, object[] __params, object __instance) { - if (__instance == null) - luaSetup.hook.Call(methodNameToHookName[__originalMethod.Name], __params); - else - luaSetup.hook.Call(methodNameToHookName[__originalMethod.Name], __instance, __params); + _hookLuaPatchPreProcess(__originalMethod, __params, __instance, out string hookName, out object[] parameters); + luaSetup.hook.Call(hookName, parameters); } + + static void HookLuaPatchRetPostfix(MethodBase __originalMethod, object[] __params, ref object __result, object __instance) { - object[] parameters; + _hookLuaPatchPreProcess(__originalMethod, __params, __instance, out string hookName, out object[] parameters); - if (__instance == null) - { - parameters = __params; - } - else - { - parameters = new object[__params.Length + 1]; - __params.CopyTo(parameters, 1); - parameters[0] = __instance; - } - - var result = new LuaResult(luaSetup.hook.Call(methodNameToHookName[__originalMethod.Name], parameters)); + var result = new LuaResult(luaSetup.hook.Call(hookName, parameters)); if (!result.IsNull()) __result = result.Object(); } - public void HookMethod(string className, string methodName, string hookName, HookMethodType hookMethodType = HookMethodType.Before) + public void HookMethod(string className, string methodName, string hookName, object paramsMap, HookMethodType hookMethodType = HookMethodType.Before) { - var classType = Type.GetType(className); - var methodInfos = classType.GetMethods(); + var @class = Type.GetType(className); + var methodInfos = @class.GetMethods(); HarmonyMethod harmonyMethod = new HarmonyMethod(); HarmonyMethod harmonyMethodRet = new HarmonyMethod(); @@ -840,11 +832,10 @@ namespace Barotrauma harmonyMethodRet = new HarmonyMethod(GetType().GetMethod("HookLuaPatchRetPrefix", BindingFlags.NonPublic | BindingFlags.Static)); } - var foundAny = false; foreach (var methodInfo in methodInfos) { - if(methodInfo.Name == methodName) + if (methodInfo.Name == methodName) { if (hookMethodType == HookMethodType.Before) if (methodInfo.ReturnType == typeof(void)) @@ -859,12 +850,22 @@ namespace Barotrauma else env.harmony.Patch(methodInfo, postfix: harmonyMethodRet); - foundAny = true; + var methodPath = $"{@class.Namespace}.{@class.Name}.{methodInfo.Name}"; + if (_methodPathToHookName.TryAdd(methodPath, hookName)) + DebugConsole.NewMessage($"Sucessfully added key-value in {nameof(_methodPathToHookName)}\n[{methodPath}, {hookName}]", Color.LightSkyBlue); + else DebugConsole.ThrowError($"Failed to add key-value in {nameof(_methodPathToHookName)}\n[{methodPath}, {hookName}]"); + + if (paramsMap != null) + { + if (_luaPatchParamsMap.TryAdd(methodPath, paramsMap)) + DebugConsole.NewMessage($"Sucessfully added key-value in {nameof(_luaPatchParamsMap)}\n[{methodPath}, {paramsMap.ToString()}]", Color.LightSkyBlue); + else DebugConsole.ThrowError($"Failed to add key-value in {nameof(_luaPatchParamsMap)}\n[{methodPath}, {paramsMap.ToString()}]"); + + } + break; } } - if(foundAny) - methodNameToHookName.Add(methodName, hookName); } public void EnqueueFunction(object function, params object[] args) From d1188a1ea5f54cc2ccf88a73cac3c72d70477f7c Mon Sep 17 00:00:00 2001 From: zhurengong <2731412072@qq.com> Date: Thu, 11 Nov 2021 17:19:06 +0800 Subject: [PATCH 2/2] do a hook call inside callback param of HookMethod, and wrapped __params --- .../BarotraumaShared/Lua/DefaultHook.lua | 30 +++-- .../SharedSource/Items/Item.cs | 10 ++ .../SharedSource/Lua/LuaClasses.cs | 110 +++++++++--------- .../SharedSource/Lua/LuaSetup.cs | 1 - 4 files changed, 86 insertions(+), 65 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Lua/DefaultHook.lua b/Barotrauma/BarotraumaShared/Lua/DefaultHook.lua index 40bfc8b70..7cdac4356 100644 --- a/Barotrauma/BarotraumaShared/Lua/DefaultHook.lua +++ b/Barotrauma/BarotraumaShared/Lua/DefaultHook.lua @@ -1,10 +1,24 @@ -Hook.HookMethod("Barotrauma.Item", "TryInteract", "itemInteract", nil) -- instance, picker, ignoreRequiredItems, forceSelectKey, forceActionKey -Hook.HookMethod("Barotrauma.Item", "Use", "itemUse", function (instance, deltaTime, character, targetLimb) return {instance, character, targetLimb} end) -Hook.HookMethod("Barotrauma.Item", "SecondaryUse", "itemSecondaryUse", function (instance, deltaTime, character) return {instance, character} end) -Hook.HookMethod("Barotrauma.Item", "ApplyTreatment", "itemApplyTreatment", nil) -- instance, user, character, targetLimb -Hook.HookMethod("Barotrauma.Item", "Combine", "itemCombine", nil) -- instance, item, user -Hook.HookMethod("Barotrauma.Item", "Drop", "itemDrop", function (instance, dropper, createNetworkEvent) return {instance, dropper} end) -Hook.HookMethod("Barotrauma.Item", "Equip", "itemEquip", nil) -- instance, character -Hook.HookMethod("Barotrauma.Item", "Unequip", "itemUnequip", nil) -- instance, character +Hook.HookMethod("Barotrauma.Item", "TryInteract", function (instance, p) + Hook.Call("itemInteract", instance, p.picker, p.ignoreRequiredItems, p.forceSelectKey, p.forceActionKey) +end, Hook.HookMethodType.Before) +Hook.HookMethod("Barotrauma.Item", "ApplyTreatment", function (instance, p) + Hook.Call("itemApplyTreatment", instance, p.user, p.character, p.targetLimb) +end, Hook.HookMethodType.Before) + +Hook.HookMethod("Barotrauma.Item", "Combine", function (instance, p) + Hook.Call("itemCombine", instance, p.item, p.user) +end, Hook.HookMethodType.Before) + +Hook.HookMethod("Barotrauma.Item", "Drop", function (instance, p) + Hook.Call("itemDrop", instance, p.dropper) +end, Hook.HookMethodType.Before) + +Hook.HookMethod("Barotrauma.Item", "Equip", function (instance, p) + Hook.Call("itemEquip", instance, p.character) +end, Hook.HookMethodType.Before) + +Hook.HookMethod("Barotrauma.Item", "Unequip", function (instance, p) + Hook.Call("itemUnequip", instance, p.character) +end, Hook.HookMethodType.Before) \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs index d1d17d44b..04a2b68b9 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs @@ -2304,6 +2304,11 @@ namespace Barotrauma if (condition == 0.0f) { return; } + var should = new LuaResult(GameMain.Lua.hook.Call("itemUse", new object[] { this, character, targetLimb })); + + if (should.Bool()) + return; + bool remove = false; foreach (ItemComponent ic in components) @@ -2337,6 +2342,11 @@ namespace Barotrauma { if (condition == 0.0f) { return; } + var should = new LuaResult(GameMain.Lua.hook.Call("itemSecondaryUse", new object[] { this, character})); + + if (should.Bool()) + return; + bool remove = false; foreach (ItemComponent ic in components) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs index e079ae849..698967aec 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaClasses.cs @@ -692,8 +692,7 @@ namespace Barotrauma public LuaHook(LuaSetup e) { env = e; - _methodPathToHookName = new Dictionary(); - _luaPatchParamsMap = new Dictionary(); + _hookMethods = new Dictionary(); } public class HookFunction @@ -712,8 +711,7 @@ namespace Barotrauma private Dictionary> hookFunctions = new Dictionary>(); - private static Dictionary _methodPathToHookName; - private static Dictionary _luaPatchParamsMap; + private static Dictionary _hookMethods; private Queue> queuedFunctionCalls = new Queue>(); @@ -722,48 +720,50 @@ namespace Barotrauma Before, After } - static void _hookLuaPatchPreProcess(MethodBase __originalMethod, object[] __params, object __instance, out string hookName, out object[] parameters) + static void _hookLuaPatch(MethodBase __originalMethod, object[] __params, object __instance, out LuaResult result, HookMethodType hookMethodType) { + // Although it works correctly, the performance is low + result = new LuaResult(null); + try { - var @class = __originalMethod.DeclaringType; - var methodPath = $"{@class.Namespace}.{@class.Name}.{__originalMethod.Name}"; + var classType = __originalMethod.DeclaringType; + var methodPath = $"{hookMethodType}:{classType.Namespace}.{classType.Name}.{__originalMethod.Name}"; - hookName = _methodPathToHookName[methodPath]; + var @params = __originalMethod.GetParameters(); + var ptable = new Dictionary(); + for (int i = 0; i < @params.Length; i++) + { + ptable.Add(@params[i].Name, __params[i]); - // Regardless of whether __instance is null or not, it's necessaray to avoid the inability to distinguish parameters when adding hooks in lua. - parameters = new object[__params.Length + 1]; - __params.CopyTo(parameters, 1); - parameters[0] = __instance; - // Map the parameters for compatibility - if (_luaPatchParamsMap.TryGetValue(methodPath, out object map)) + } + + if (_hookMethods.TryGetValue(methodPath, out object hookMethod)) { - var result = luaSetup.hook.env.lua.Call(map, parameters); - if (!result.IsNil()) parameters = result.ToObject(); + result = new LuaResult(luaSetup.hook.env.lua.Call(hookMethod, __instance, ptable)); + } + else + { + DebugConsole.ThrowError($"No hook method found in _hookMethods[{methodPath}]"); } } catch (Exception ex) { - parameters = null; - hookName = null; - DebugConsole.ThrowError(nameof(_hookLuaPatchPreProcess), ex); + DebugConsole.ThrowError(nameof(_hookLuaPatch), ex); } } static bool HookLuaPatchPrefix(MethodBase __originalMethod, object[] __params, object __instance) { - _hookLuaPatchPreProcess(__originalMethod, __params, __instance, out string hookName, out object[] parameters); - - var result = new LuaResult(luaSetup.hook.Call(hookName, parameters)); + _hookLuaPatch(__originalMethod, __params, __instance, out LuaResult result, HookMethodType.Before); + return result.IsNull(); } static bool HookLuaPatchRetPrefix(MethodBase __originalMethod, object[] __params, ref object __result, object __instance) { - _hookLuaPatchPreProcess(__originalMethod, __params, __instance, out string hookName, out object[] parameters); - - var result = new LuaResult(luaSetup.hook.Call(hookName, parameters)); + _hookLuaPatch(__originalMethod, __params, __instance, out LuaResult result, HookMethodType.Before); if (!result.IsNull()) { @@ -776,71 +776,69 @@ namespace Barotrauma static void HookLuaPatchPostfix(MethodBase __originalMethod, object[] __params, object __instance) { - _hookLuaPatchPreProcess(__originalMethod, __params, __instance, out string hookName, out object[] parameters); - luaSetup.hook.Call(hookName, parameters); + _hookLuaPatch(__originalMethod, __params, __instance, out LuaResult result, HookMethodType.After); } - - static void HookLuaPatchRetPostfix(MethodBase __originalMethod, object[] __params, ref object __result, object __instance) { - _hookLuaPatchPreProcess(__originalMethod, __params, __instance, out string hookName, out object[] parameters); - - var result = new LuaResult(luaSetup.hook.Call(hookName, parameters)); + _hookLuaPatch(__originalMethod, __params, __instance, out LuaResult result, HookMethodType.After); if (!result.IsNull()) __result = result.Object(); } - public void HookMethod(string className, string methodName, string hookName, object paramsMap, HookMethodType hookMethodType = HookMethodType.Before) + private static MethodInfo _miHookLuaPatchPrefix = typeof(LuaHook).GetMethod("HookLuaPatchPrefix", BindingFlags.NonPublic | BindingFlags.Static); + private static MethodInfo _miHookLuaPatchRetPrefix = typeof(LuaHook).GetMethod("HookLuaPatchRetPrefix", BindingFlags.NonPublic | BindingFlags.Static); + private static MethodInfo _miHookLuaPatchPostfix = typeof(LuaHook).GetMethod("HookLuaPatchPostfix", BindingFlags.NonPublic | BindingFlags.Static); + private static MethodInfo _miHookLuaPatchRetPostfix = typeof(LuaHook).GetMethod("HookLuaPatchRetPostfix", BindingFlags.NonPublic | BindingFlags.Static); + public void HookMethod(string className, string methodName, object hookMethod, HookMethodType hookMethodType = HookMethodType.Before) { - var @class = Type.GetType(className); - var methodInfos = @class.GetMethods(); + var classType = Type.GetType(className); + var methodInfos = classType.GetMethods(); HarmonyMethod harmonyMethod = new HarmonyMethod(); HarmonyMethod harmonyMethodRet = new HarmonyMethod(); if (hookMethodType == HookMethodType.Before) { - harmonyMethod = new HarmonyMethod(GetType().GetMethod("HookLuaPatchPrefix", BindingFlags.NonPublic | BindingFlags.Static)); - - harmonyMethodRet = new HarmonyMethod(GetType().GetMethod("HookLuaPatchRetPrefix", BindingFlags.NonPublic | BindingFlags.Static)); + harmonyMethod = new HarmonyMethod(_miHookLuaPatchPrefix); + harmonyMethodRet = new HarmonyMethod(_miHookLuaPatchRetPrefix); } else if (hookMethodType == HookMethodType.After) { - harmonyMethod = new HarmonyMethod(GetType().GetMethod("HookLuaPatchPostfix", BindingFlags.NonPublic | BindingFlags.Static)); - - harmonyMethodRet = new HarmonyMethod(GetType().GetMethod("HookLuaPatchRetPrefix", BindingFlags.NonPublic | BindingFlags.Static)); + harmonyMethod = new HarmonyMethod(_miHookLuaPatchPostfix); + harmonyMethodRet = new HarmonyMethod(_miHookLuaPatchRetPostfix); } - foreach (var methodInfo in methodInfos) { if (methodInfo.Name == methodName) { if (hookMethodType == HookMethodType.Before) + { if (methodInfo.ReturnType == typeof(void)) - env.harmony.Patch(methodInfo, harmonyMethod); + env.harmony.Patch(methodInfo, prefix: harmonyMethod); else - env.harmony.Patch(methodInfo, harmonyMethodRet); - - + env.harmony.Patch(methodInfo, prefix: harmonyMethodRet); + } else if (hookMethodType == HookMethodType.After) + { if (methodInfo.ReturnType == typeof(void)) env.harmony.Patch(methodInfo, postfix: harmonyMethod); else env.harmony.Patch(methodInfo, postfix: harmonyMethodRet); + } - var methodPath = $"{@class.Namespace}.{@class.Name}.{methodInfo.Name}"; - if (_methodPathToHookName.TryAdd(methodPath, hookName)) - DebugConsole.NewMessage($"Sucessfully added key-value in {nameof(_methodPathToHookName)}\n[{methodPath}, {hookName}]", Color.LightSkyBlue); - else DebugConsole.ThrowError($"Failed to add key-value in {nameof(_methodPathToHookName)}\n[{methodPath}, {hookName}]"); - - if (paramsMap != null) + // build an unique method path by patch type, class, method self + var methodPath = $"{hookMethodType}:{classType.Namespace}.{classType.Name}.{methodInfo.Name}"; + + if (hookMethod != null) { - if (_luaPatchParamsMap.TryAdd(methodPath, paramsMap)) - DebugConsole.NewMessage($"Sucessfully added key-value in {nameof(_luaPatchParamsMap)}\n[{methodPath}, {paramsMap.ToString()}]", Color.LightSkyBlue); - else DebugConsole.ThrowError($"Failed to add key-value in {nameof(_luaPatchParamsMap)}\n[{methodPath}, {paramsMap.ToString()}]"); - + if (!_hookMethods.TryAdd(methodPath, hookMethod)) + DebugConsole.ThrowError($"Failed to add key-value in {nameof(_hookMethods)}\n[{methodPath}, {hookMethod.ToString()}]"); +#if DEBUG + else + DebugConsole.NewMessage($"Sucessfully added key-value in {nameof(_hookMethods)}\n[{methodPath}, {hookMethod.ToString()}]", Color.LightSkyBlue); +#endif } break; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaSetup.cs b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaSetup.cs index feb05ffea..b10afe263 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaSetup.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Lua/LuaSetup.cs @@ -324,7 +324,6 @@ namespace Barotrauma UserData.RegisterType(); UserData.RegisterType(); UserData.RegisterType(); - UserData.RegisterType(); UserData.RegisterType();