It works. Except (HookMethod->Harmony: L189) is throwing NRE.

This commit is contained in:
MapleWheels
2026-02-02 20:45:09 -05:00
committed by Maplewheels
parent 2eb593f461
commit 06348d3ba5
7 changed files with 69 additions and 66 deletions
@@ -17,12 +17,12 @@ public interface ILuaCsHook : ILuaCsShim
T Call<T>(string eventName, params object[] args); T Call<T>(string eventName, params object[] args);
// Hook/Method Patching // Hook/Method Patching
string Patch(string identifier, string className, string methodName, string[] parameterTypes, LuaCsPatchFunc patch, EventService.HookMethodType hookType = EventService.HookMethodType.Before); string Patch(string identifier, string className, string methodName, string[] parameterTypes, LuaCsPatchFunc patch, HookMethodType hookType = HookMethodType.Before);
string Patch(string identifier, string className, string methodName, LuaCsPatchFunc patch, EventService.HookMethodType hookType = EventService.HookMethodType.Before); string Patch(string identifier, string className, string methodName, LuaCsPatchFunc patch, HookMethodType hookType = HookMethodType.Before);
string Patch(string className, string methodName, string[] parameterTypes, LuaCsPatchFunc patch, EventService.HookMethodType hookType = EventService.HookMethodType.Before); string Patch(string className, string methodName, string[] parameterTypes, LuaCsPatchFunc patch, HookMethodType hookType = HookMethodType.Before);
string Patch(string className, string methodName, LuaCsPatchFunc patch, EventService.HookMethodType hookType = EventService.HookMethodType.Before); string Patch(string className, string methodName, LuaCsPatchFunc patch, HookMethodType hookType = HookMethodType.Before);
bool RemovePatch(string identifier, string className, string methodName, string[] parameterTypes, EventService.HookMethodType hookType); bool RemovePatch(string identifier, string className, string methodName, string[] parameterTypes, HookMethodType hookType);
bool RemovePatch(string identifier, string className, string methodName, EventService.HookMethodType hookType); bool RemovePatch(string identifier, string className, string methodName, HookMethodType hookType);
void HookMethod(string identifier, MethodBase method, LuaCsCompatPatchFunc patch, HookMethodType hookType = HookMethodType.Before, IAssemblyPlugin owner = null); void HookMethod(string identifier, MethodBase method, LuaCsCompatPatchFunc patch, HookMethodType hookType = HookMethodType.Before, IAssemblyPlugin owner = null);
@@ -477,7 +477,7 @@ public class PluginManagementService : IAssemblyManagementService
IEnumerable<MetadataReference> GetMetadataReferences() IEnumerable<MetadataReference> GetMetadataReferences()
{ {
#if !DEBUG #if !DEBUG
throw new NotImplementedException($"Needs to use publicized barotrauma assemblies."); throw new NotImplementedException($"Needs to use publicized barotrauma assemblies and cache metadata.");
#endif #endif
return Basic.Reference.Assemblies.Net80.References.All return Basic.Reference.Assemblies.Net80.References.All
.Union(AppDomain.CurrentDomain.GetAssemblies() .Union(AppDomain.CurrentDomain.GetAssemblies()
@@ -303,6 +303,7 @@ public sealed class ModConfigService : IModConfigService
FriendlyName = IAssemblyLoaderService.InternalsAwareAssemblyName, FriendlyName = IAssemblyLoaderService.InternalsAwareAssemblyName,
IncompatiblePackages = ImmutableArray<Identifier>.Empty, IncompatiblePackages = ImmutableArray<Identifier>.Empty,
RequiredPackages = ImmutableArray<Identifier>.Empty, RequiredPackages = ImmutableArray<Identifier>.Empty,
UseInternalAccessName = true,
IsScript = true IsScript = true
}); });
} }
@@ -416,11 +416,6 @@ namespace Barotrauma.LuaCs.Services
partial class EventService partial class EventService
{ {
public enum HookMethodType
{
Before, After
}
private class LuaCsHookCallback private class LuaCsHookCallback
{ {
public string name; public string name;
@@ -805,7 +800,7 @@ namespace Barotrauma.LuaCs.Services
// If you need to debug this: // If you need to debug this:
// - use https://sharplab.io ; it's a very useful for resource for writing IL by hand. // - use https://sharplab.io ; it's a very useful for resource for writing IL by hand.
// - use il.NewMessage("") or il.WriteLine("") to see where the IL crashes at runtime. // - use il.NewMessage("") or il.WriteLine("") to see where the IL crashes at runtime.
private MethodInfo CreateDynamicHarmonyPatch(string identifier, MethodBase original, HookMethodType hookType) private MethodInfo CreateDynamicHarmonyPatch(string identifier, MethodBase original, LuaCsHook.HookMethodType hookType)
{ {
var parameters = new List<DynamicParameterMapping> var parameters = new List<DynamicParameterMapping>
{ {
@@ -840,9 +835,9 @@ namespace Barotrauma.LuaCs.Services
var luaCsField = typeBuilder.DefineField(FIELD_LUACS, typeof(LuaCsSetup), FieldAttributes.Public | FieldAttributes.Static); var luaCsField = typeBuilder.DefineField(FIELD_LUACS, typeof(LuaCsSetup), FieldAttributes.Public | FieldAttributes.Static);
var methodName = hookType == HookMethodType.Before ? "HarmonyPrefix" : "HarmonyPostfix"; var methodName = hookType == LuaCsHook.HookMethodType.Before ? "HarmonyPrefix" : "HarmonyPostfix";
var il = Emit.BuildMethod( var il = Emit.BuildMethod(
returnType: hookType == HookMethodType.Before ? typeof(bool) : typeof(void), returnType: hookType == LuaCsHook.HookMethodType.Before ? typeof(bool) : typeof(void),
parameterTypes: parameters.Select(x => x.HarmonyPatchParamType).ToArray(), parameterTypes: parameters.Select(x => x.HarmonyPatchParamType).ToArray(),
type: typeBuilder, type: typeBuilder,
name: methodName, name: methodName,
@@ -911,7 +906,7 @@ namespace Barotrauma.LuaCs.Services
il.NewObject(typeof(ParameterTable), typeof(Dictionary<string, object>)); il.NewObject(typeof(ParameterTable), typeof(Dictionary<string, object>));
il.StoreLocal(ptable); il.StoreLocal(ptable);
if (hasReturnType && hookType == HookMethodType.After) if (hasReturnType && hookType == LuaCsHook.HookMethodType.After)
{ {
// IL: ptable.OriginalReturnValue = __result; // IL: ptable.OriginalReturnValue = __result;
il.LoadLocal(ptable); il.LoadLocal(ptable);
@@ -924,7 +919,7 @@ namespace Barotrauma.LuaCs.Services
var enumerator = il.DeclareLocal<IEnumerator<LuaCsPatch>>("enumerator"); var enumerator = il.DeclareLocal<IEnumerator<LuaCsPatch>>("enumerator");
il.LoadLocal(patches); il.LoadLocal(patches);
il.CallVirtual(typeof(PatchedMethod).GetMethod( il.CallVirtual(typeof(PatchedMethod).GetMethod(
name: hookType == HookMethodType.Before name: hookType == LuaCsHook.HookMethodType.Before
? nameof(PatchedMethod.GetPrefixEnumerator) ? nameof(PatchedMethod.GetPrefixEnumerator)
: nameof(PatchedMethod.GetPostfixEnumerator), : nameof(PatchedMethod.GetPostfixEnumerator),
bindingAttr: BindingFlags.Public | BindingFlags.Instance)); bindingAttr: BindingFlags.Public | BindingFlags.Instance));
@@ -1073,7 +1068,7 @@ namespace Barotrauma.LuaCs.Services
il.EndExceptionBlock(exceptionBlock); il.EndExceptionBlock(exceptionBlock);
// Only prefixes return a bool // Only prefixes return a bool
if (hookType == HookMethodType.Before) if (hookType == LuaCsHook.HookMethodType.Before)
{ {
il.LoadLocal(harmonyReturnValue); il.LoadLocal(harmonyReturnValue);
} }
@@ -1090,7 +1085,7 @@ namespace Barotrauma.LuaCs.Services
return type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static); return type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static);
} }
private string Patch(string identifier, MethodBase method, LuaCsPatchFunc patch, HookMethodType hookType = HookMethodType.Before) private string Patch(string identifier, MethodBase method, LuaCsPatchFunc patch, LuaCsHook.HookMethodType hookType = LuaCsHook.HookMethodType.Before)
{ {
if (method == null) throw new ArgumentNullException(nameof(method)); if (method == null) throw new ArgumentNullException(nameof(method));
if (patch == null) throw new ArgumentNullException(nameof(patch)); if (patch == null) throw new ArgumentNullException(nameof(patch));
@@ -1102,13 +1097,13 @@ namespace Barotrauma.LuaCs.Services
var patchKey = MethodKey.Create(method); var patchKey = MethodKey.Create(method);
if (!registeredPatches.TryGetValue(patchKey, out var methodPatches)) if (!registeredPatches.TryGetValue(patchKey, out var methodPatches))
{ {
var harmonyPrefix = CreateDynamicHarmonyPatch(identifier, method, HookMethodType.Before); var harmonyPrefix = CreateDynamicHarmonyPatch(identifier, method, LuaCsHook.HookMethodType.Before);
var harmonyPostfix = CreateDynamicHarmonyPatch(identifier, method, HookMethodType.After); var harmonyPostfix = CreateDynamicHarmonyPatch(identifier, method, LuaCsHook.HookMethodType.After);
harmony.Patch(method, prefix: new HarmonyMethod(harmonyPrefix), postfix: new HarmonyMethod(harmonyPostfix)); harmony.Patch(method, prefix: new HarmonyMethod(harmonyPrefix), postfix: new HarmonyMethod(harmonyPostfix));
methodPatches = registeredPatches[patchKey] = new PatchedMethod(harmonyPrefix, harmonyPostfix); methodPatches = registeredPatches[patchKey] = new PatchedMethod(harmonyPrefix, harmonyPostfix);
} }
if (hookType == HookMethodType.Before) if (hookType == LuaCsHook.HookMethodType.Before)
{ {
if (methodPatches.Prefixes.Remove(identifier)) if (methodPatches.Prefixes.Remove(identifier))
{ {
@@ -1121,7 +1116,7 @@ namespace Barotrauma.LuaCs.Services
PatchFunc = patch, PatchFunc = patch,
}); });
} }
else if (hookType == HookMethodType.After) else if (hookType == LuaCsHook.HookMethodType.After)
{ {
if (methodPatches.Postfixes.Remove(identifier)) if (methodPatches.Postfixes.Remove(identifier))
{ {
@@ -1138,31 +1133,31 @@ namespace Barotrauma.LuaCs.Services
return identifier; return identifier;
} }
public string Patch(string identifier, string className, string methodName, string[] parameterTypes, LuaCsPatchFunc patch, HookMethodType hookType = HookMethodType.Before) public string Patch(string identifier, string className, string methodName, string[] parameterTypes, LuaCsPatchFunc patch, LuaCsHook.HookMethodType hookType = LuaCsHook.HookMethodType.Before)
{ {
var method = ResolveMethod(className, methodName, parameterTypes); var method = ResolveMethod(className, methodName, parameterTypes);
return Patch(identifier, method, patch, hookType); return Patch(identifier, method, patch, hookType);
} }
public string Patch(string identifier, string className, string methodName, LuaCsPatchFunc patch, HookMethodType hookType = HookMethodType.Before) public string Patch(string identifier, string className, string methodName, LuaCsPatchFunc patch, LuaCsHook.HookMethodType hookType = LuaCsHook.HookMethodType.Before)
{ {
var method = ResolveMethod(className, methodName, null); var method = ResolveMethod(className, methodName, null);
return Patch(identifier, method, patch, hookType); return Patch(identifier, method, patch, hookType);
} }
public string Patch(string className, string methodName, string[] parameterTypes, LuaCsPatchFunc patch, HookMethodType hookType = HookMethodType.Before) public string Patch(string className, string methodName, string[] parameterTypes, LuaCsPatchFunc patch, LuaCsHook.HookMethodType hookType = LuaCsHook.HookMethodType.Before)
{ {
var method = ResolveMethod(className, methodName, parameterTypes); var method = ResolveMethod(className, methodName, parameterTypes);
return Patch(null, method, patch, hookType); return Patch(null, method, patch, hookType);
} }
public string Patch(string className, string methodName, LuaCsPatchFunc patch, HookMethodType hookType = HookMethodType.Before) public string Patch(string className, string methodName, LuaCsPatchFunc patch, LuaCsHook.HookMethodType hookType = LuaCsHook.HookMethodType.Before)
{ {
var method = ResolveMethod(className, methodName, null); var method = ResolveMethod(className, methodName, null);
return Patch(null, method, patch, hookType); return Patch(null, method, patch, hookType);
} }
private bool RemovePatch(string identifier, MethodBase method, HookMethodType hookType) private bool RemovePatch(string identifier, MethodBase method, LuaCsHook.HookMethodType hookType)
{ {
if (identifier == null) throw new ArgumentNullException(nameof(identifier)); if (identifier == null) throw new ArgumentNullException(nameof(identifier));
identifier = NormalizeIdentifier(identifier); identifier = NormalizeIdentifier(identifier);
@@ -1175,19 +1170,19 @@ namespace Barotrauma.LuaCs.Services
return hookType switch return hookType switch
{ {
HookMethodType.Before => methodPatches.Prefixes.Remove(identifier), LuaCsHook.HookMethodType.Before => methodPatches.Prefixes.Remove(identifier),
HookMethodType.After => methodPatches.Postfixes.Remove(identifier), LuaCsHook.HookMethodType.After => methodPatches.Postfixes.Remove(identifier),
_ => throw new ArgumentException($"Invalid {nameof(HookMethodType)} enum value.", nameof(hookType)), _ => throw new ArgumentException($"Invalid {nameof(LuaCsHook.HookMethodType)} enum value.", nameof(hookType)),
}; };
} }
public bool RemovePatch(string identifier, string className, string methodName, string[] parameterTypes, HookMethodType hookType) public bool RemovePatch(string identifier, string className, string methodName, string[] parameterTypes, LuaCsHook.HookMethodType hookType)
{ {
var method = ResolveMethod(className, methodName, parameterTypes); var method = ResolveMethod(className, methodName, parameterTypes);
return RemovePatch(identifier, method, hookType); return RemovePatch(identifier, method, hookType);
} }
public bool RemovePatch(string identifier, string className, string methodName, HookMethodType hookType) public bool RemovePatch(string identifier, string className, string methodName, LuaCsHook.HookMethodType hookType)
{ {
var method = ResolveMethod(className, methodName, null); var method = ResolveMethod(className, methodName, null);
return RemovePatch(identifier, method, hookType); return RemovePatch(identifier, method, hookType);
@@ -23,7 +23,7 @@ namespace Barotrauma.LuaCs.Services
private Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>> compatHookPrefixMethods = new Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>>(); private Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>> compatHookPrefixMethods = new Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>>();
private Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>> compatHookPostfixMethods = new Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>>(); private Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>> compatHookPostfixMethods = new Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>>();
private static void _hookLuaCsPatch(MethodBase __originalMethod, object[] __args, object __instance, out object result, HookMethodType hookType) private static void _hookLuaCsPatch(MethodBase __originalMethod, object[] __args, object __instance, out object result, ILuaCsHook.HookMethodType hookType)
{ {
result = null; result = null;
@@ -33,14 +33,14 @@ namespace Barotrauma.LuaCs.Services
HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)> methodSet = null; HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)> methodSet = null;
switch (hookType) switch (hookType)
{ {
case HookMethodType.Before: case ILuaCsHook.HookMethodType.Before:
instance.compatHookPrefixMethods.TryGetValue(funcAddr, out methodSet); instance.compatHookPrefixMethods.TryGetValue(funcAddr, out methodSet);
break; break;
case HookMethodType.After: case ILuaCsHook.HookMethodType.After:
instance.compatHookPostfixMethods.TryGetValue(funcAddr, out methodSet); instance.compatHookPostfixMethods.TryGetValue(funcAddr, out methodSet);
break; break;
default: default:
throw new ArgumentException($"Invalid {nameof(HookMethodType)} enum value.", nameof(hookType)); throw new ArgumentException($"Invalid {nameof(ILuaCsHook.HookMethodType)} enum value.", nameof(hookType));
} }
if (methodSet != null) if (methodSet != null)
@@ -98,16 +98,16 @@ namespace Barotrauma.LuaCs.Services
private static bool HookLuaCsPatchPrefix(MethodBase __originalMethod, object[] __args, object __instance) private static bool HookLuaCsPatchPrefix(MethodBase __originalMethod, object[] __args, object __instance)
{ {
_hookLuaCsPatch(__originalMethod, __args, __instance, out object result, HookMethodType.Before); _hookLuaCsPatch(__originalMethod, __args, __instance, out object result, ILuaCsHook.HookMethodType.Before);
return result == null; return result == null;
} }
private static void HookLuaCsPatchPostfix(MethodBase __originalMethod, object[] __args, object __instance) => private static void HookLuaCsPatchPostfix(MethodBase __originalMethod, object[] __args, object __instance) =>
_hookLuaCsPatch(__originalMethod, __args, __instance, out object _, HookMethodType.After); _hookLuaCsPatch(__originalMethod, __args, __instance, out object _, ILuaCsHook.HookMethodType.After);
private static bool HookLuaCsPatchRetPrefix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance) private static bool HookLuaCsPatchRetPrefix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance)
{ {
_hookLuaCsPatch(__originalMethod, __args, __instance, out object result, HookMethodType.Before); _hookLuaCsPatch(__originalMethod, __args, __instance, out object result, ILuaCsHook.HookMethodType.Before);
if (result != null) if (result != null)
{ {
__result = result; __result = result;
@@ -118,7 +118,7 @@ namespace Barotrauma.LuaCs.Services
private static void HookLuaCsPatchRetPostfix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance) private static void HookLuaCsPatchRetPostfix(MethodBase __originalMethod, object[] __args, ref object __result, object __instance)
{ {
_hookLuaCsPatch(__originalMethod, __args, __instance, out object result, HookMethodType.After); _hookLuaCsPatch(__originalMethod, __args, __instance, out object result, ILuaCsHook.HookMethodType.After);
if (result != null) __result = result; if (result != null) __result = result;
} }
@@ -130,10 +130,6 @@ namespace Barotrauma.LuaCs.Services
// TODO: deprecate this // TODO: deprecate this
public void HookMethod(string identifier, MethodBase method, LuaCsCompatPatchFunc patch, ILuaCsHook.HookMethodType hookType = ILuaCsHook.HookMethodType.Before, IAssemblyPlugin owner = null) public void HookMethod(string identifier, MethodBase method, LuaCsCompatPatchFunc patch, ILuaCsHook.HookMethodType hookType = ILuaCsHook.HookMethodType.Before, IAssemblyPlugin owner = null)
{
throw new NotImplementedException();
}
public void HookMethod(string identifier, MethodBase method, LuaCsCompatPatchFunc patch, HookMethodType hookType = HookMethodType.Before, IAssemblyPlugin owner = null)
{ {
if (identifier == null || method == null || patch == null) if (identifier == null || method == null || patch == null)
{ {
@@ -145,7 +141,7 @@ namespace Barotrauma.LuaCs.Services
var funcAddr = ((long)method.MethodHandle.GetFunctionPointer()); var funcAddr = ((long)method.MethodHandle.GetFunctionPointer());
var patches = Harmony.GetPatchInfo(method); var patches = Harmony.GetPatchInfo(method);
if (hookType == HookMethodType.Before) if (hookType == ILuaCsHook.HookMethodType.Before)
{ {
if (method is MethodInfo mi && mi.ReturnType != typeof(void)) if (method is MethodInfo mi && mi.ReturnType != typeof(void))
{ {
@@ -177,7 +173,7 @@ namespace Barotrauma.LuaCs.Services
} }
} }
else if (hookType == HookMethodType.After) else if (hookType == ILuaCsHook.HookMethodType.After)
{ {
if (method is MethodInfo mi && mi.ReturnType != typeof(void)) if (method is MethodInfo mi && mi.ReturnType != typeof(void))
{ {
@@ -209,7 +205,7 @@ namespace Barotrauma.LuaCs.Services
} }
} }
} }
protected void HookMethod(string identifier, string className, string methodName, string[] parameterNames, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) protected void HookMethod(string identifier, string className, string methodName, string[] parameterNames, LuaCsCompatPatchFunc patch, ILuaCsHook.HookMethodType hookMethodType = ILuaCsHook.HookMethodType.Before)
{ {
var method = ResolveMethod(className, methodName, parameterNames); var method = ResolveMethod(className, methodName, parameterNames);
if (method == null) return; if (method == null) return;
@@ -219,26 +215,26 @@ namespace Barotrauma.LuaCs.Services
} }
HookMethod(identifier, method, patch, hookMethodType); HookMethod(identifier, method, patch, hookMethodType);
} }
protected void HookMethod(string identifier, string className, string methodName, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) => protected void HookMethod(string identifier, string className, string methodName, LuaCsCompatPatchFunc patch, ILuaCsHook.HookMethodType hookMethodType = ILuaCsHook.HookMethodType.Before) =>
HookMethod(identifier, className, methodName, null, patch, hookMethodType); HookMethod(identifier, className, methodName, null, patch, hookMethodType);
protected void HookMethod(string className, string methodName, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) => protected void HookMethod(string className, string methodName, LuaCsCompatPatchFunc patch, ILuaCsHook.HookMethodType hookMethodType = ILuaCsHook.HookMethodType.Before) =>
HookMethod("", className, methodName, null, patch, hookMethodType); HookMethod("", className, methodName, null, patch, hookMethodType);
protected void HookMethod(string className, string methodName, string[] parameterNames, LuaCsCompatPatchFunc patch, HookMethodType hookMethodType = HookMethodType.Before) => protected void HookMethod(string className, string methodName, string[] parameterNames, LuaCsCompatPatchFunc patch, ILuaCsHook.HookMethodType hookMethodType = ILuaCsHook.HookMethodType.Before) =>
HookMethod("", className, methodName, parameterNames, patch, hookMethodType); HookMethod("", className, methodName, parameterNames, patch, hookMethodType);
public void UnhookMethod(string identifier, MethodBase method, HookMethodType hookType = HookMethodType.Before) public void UnhookMethod(string identifier, MethodBase method, ILuaCsHook.HookMethodType hookType = ILuaCsHook.HookMethodType.Before)
{ {
var funcAddr = (long)method.MethodHandle.GetFunctionPointer(); var funcAddr = (long)method.MethodHandle.GetFunctionPointer();
Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>> methods; Dictionary<long, HashSet<(string, LuaCsCompatPatchFunc, IAssemblyPlugin)>> methods;
if (hookType == HookMethodType.Before) methods = compatHookPrefixMethods; if (hookType == ILuaCsHook.HookMethodType.Before) methods = compatHookPrefixMethods;
else if (hookType == HookMethodType.After) methods = compatHookPostfixMethods; else if (hookType == ILuaCsHook.HookMethodType.After) methods = compatHookPostfixMethods;
else throw null; else throw null;
if (methods.ContainsKey(funcAddr)) methods[funcAddr]?.RemoveWhere(t => t.Item1 == identifier); if (methods.ContainsKey(funcAddr)) methods[funcAddr]?.RemoveWhere(t => t.Item1 == identifier);
} }
protected void UnhookMethod(string identifier, string className, string methodName, string[] parameterNames, HookMethodType hookType = HookMethodType.Before) protected void UnhookMethod(string identifier, string className, string methodName, string[] parameterNames, ILuaCsHook.HookMethodType hookType = ILuaCsHook.HookMethodType.Before)
{ {
var method = ResolveMethod(className, methodName, parameterNames); var method = ResolveMethod(className, methodName, parameterNames);
if (method == null) return; if (method == null) return;
@@ -11,6 +11,16 @@ using Microsoft.CodeAnalysis.CSharp;
namespace Barotrauma.LuaCs; namespace Barotrauma.LuaCs;
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class IgnoresAccessChecksToAttribute : Attribute
{
public string AssemblyName { get; }
public IgnoresAccessChecksToAttribute(string assemblyName)
{
AssemblyName = assemblyName;
}
}
public interface IAssemblyLoaderService : IService public interface IAssemblyLoaderService : IService
{ {
public interface IFactory : IService public interface IFactory : IService
@@ -1,5 +1,5 @@
extern alias Client; extern alias Client;
extern alias Server;
using Client::Barotrauma.LuaCs.Services; using Client::Barotrauma.LuaCs.Services;
using Client::Barotrauma; using Client::Barotrauma;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
@@ -8,6 +8,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using Server::Barotrauma.LuaCs.Services.Compatibility;
using Xunit; using Xunit;
namespace TestProject.LuaCs namespace TestProject.LuaCs
@@ -64,14 +65,14 @@ namespace TestProject.LuaCs
string methodName, string methodName,
string[]? parameters, string[]? parameters,
string function, string function,
EventService.HookMethodType patchType) ILuaCsHook.HookMethodType patchType)
{ {
var args = BuildHookPatchArgsList(patchId, className, methodName, parameters); var args = BuildHookPatchArgsList(patchId, className, methodName, parameters);
args.Add(function); args.Add(function);
args.Add(patchType switch args.Add(patchType switch
{ {
EventService.HookMethodType.Before => "Hook.HookMethodType.Before", ILuaCsHook.HookMethodType.Before => "Hook.HookMethodType.Before",
EventService.HookMethodType.After => "Hook.HookMethodType.After", ILuaCsHook.HookMethodType.After => "Hook.HookMethodType.After",
_ => throw new NotImplementedException(), _ => throw new NotImplementedException(),
}); });
throw new NotImplementedException(); throw new NotImplementedException();
@@ -84,13 +85,13 @@ namespace TestProject.LuaCs
string className, string className,
string methodName, string methodName,
string[]? parameters, string[]? parameters,
EventService.HookMethodType patchType) ILuaCsHook.HookMethodType patchType)
{ {
var args = BuildHookPatchArgsList(patchId, className, methodName, parameters); var args = BuildHookPatchArgsList(patchId, className, methodName, parameters);
args.Add(patchType switch args.Add(patchType switch
{ {
EventService.HookMethodType.Before => "Hook.HookMethodType.Before", ILuaCsHook.HookMethodType.Before => "Hook.HookMethodType.Before",
EventService.HookMethodType.After => "Hook.HookMethodType.After", ILuaCsHook.HookMethodType.After => "Hook.HookMethodType.After",
_ => throw new NotImplementedException(), _ => throw new NotImplementedException(),
}); });
throw new NotImplementedException(); throw new NotImplementedException();
@@ -104,7 +105,7 @@ namespace TestProject.LuaCs
function(instance, ptable) function(instance, ptable)
{body} {body}
end end
", EventService.HookMethodType.Before); ", ILuaCsHook.HookMethodType.Before);
Assert.Equal(DataType.String, returnValue.Type); Assert.Equal(DataType.String, returnValue.Type);
return new(returnValue.String, () => luaCs.RemovePrefix<T>(returnValue.String, methodName, parameters)); return new(returnValue.String, () => luaCs.RemovePrefix<T>(returnValue.String, methodName, parameters));
} }
@@ -116,7 +117,7 @@ namespace TestProject.LuaCs
function(instance, ptable) function(instance, ptable)
{body} {body}
end end
", EventService.HookMethodType.After); ", ILuaCsHook.HookMethodType.After);
Assert.Equal(DataType.String, returnValue.Type); Assert.Equal(DataType.String, returnValue.Type);
return new(returnValue.String, () => luaCs.RemovePostfix<T>(returnValue.String, methodName, parameters)); return new(returnValue.String, () => luaCs.RemovePostfix<T>(returnValue.String, methodName, parameters));
} }
@@ -124,7 +125,7 @@ namespace TestProject.LuaCs
public static bool RemovePrefix<T>(this LuaCsSetup luaCs, string patchId, string methodName, string[]? parameters = null) public static bool RemovePrefix<T>(this LuaCsSetup luaCs, string patchId, string methodName, string[]? parameters = null)
{ {
var className = typeof(T).FullName!; var className = typeof(T).FullName!;
var returnValue = luaCs.DoHookRemovePatch(patchId, className, methodName, parameters, EventService.HookMethodType.Before); var returnValue = luaCs.DoHookRemovePatch(patchId, className, methodName, parameters, ILuaCsHook.HookMethodType.Before);
Assert.Equal(DataType.Boolean, returnValue.Type); Assert.Equal(DataType.Boolean, returnValue.Type);
return returnValue.Boolean; return returnValue.Boolean;
} }
@@ -132,7 +133,7 @@ namespace TestProject.LuaCs
public static bool RemovePostfix<T>(this LuaCsSetup luaCs, string patchId, string methodName, string[]? parameters = null) public static bool RemovePostfix<T>(this LuaCsSetup luaCs, string patchId, string methodName, string[]? parameters = null)
{ {
var className = typeof(T).FullName!; var className = typeof(T).FullName!;
var returnValue = luaCs.DoHookRemovePatch(patchId, className, methodName, parameters, EventService.HookMethodType.After); var returnValue = luaCs.DoHookRemovePatch(patchId, className, methodName, parameters, ILuaCsHook.HookMethodType.After);
Assert.Equal(DataType.Boolean, returnValue.Type); Assert.Equal(DataType.Boolean, returnValue.Type);
return returnValue.Boolean; return returnValue.Boolean;
} }