예제 #1
0
 public static void Dispose()
 {
     foreach (var kv in _Hooks)
     {
         kv.Value.Dispose();
         RuntimeHooks.DeleteDetour(kv.Key);
     }
 }
예제 #2
0
 public static void DeinitializeLua()
 {
     if (Unload != null)
     {
         SafeExecLua(Unload, "running stock.unload");
     }
     RuntimeHooks.DeleteAllDetours();
     LuaState.Dispose();
     LuaState = null;
     Unload   = null;
     Ready    = null;
 }
예제 #3
0
 public static void Hook(LuaTable details, LuaFunction fn)
 {
     RuntimeHooks.Add(details, fn);
 }
예제 #4
0
        public static void Add(LuaTable details, LuaFunction fn)
        {
            Type   criteria_type;
            string criteria_methodname;

            Type[] criteria_argtypes = null;
            bool   criteria_instance;
            bool   criteria_public;
            bool   hook_returns;

            using (var ftype = details["type"]) {
                if (ftype == null)
                {
                    throw new LuaException($"type: Expected Type, got null");
                }
                if (!(ftype is IClrObject))
                {
                    throw new LuaException($"type: Expected CLR Type object, got non-CLR object of type {ftype.GetType()}");
                }
                else if (!(((IClrObject)ftype).ClrObject is Type))
                {
                    throw new LuaException($"type: Expected CLR Type object, got CLR object of type {((IClrObject)ftype).ClrObject.GetType()}");
                }

                criteria_type = ((IClrObject)ftype).ClrObject as Type;
                using (var method = details["method"] as LuaString)
                    using (var instance = details["instance"] as LuaBoolean)
                        using (var @public = details["public"] as LuaBoolean)
                            using (var returns = details["returns"] as LuaBoolean)
                                using (var args = details["args"] as LuaTable) {
                                    if (method == null)
                                    {
                                        throw new LuaException("method: Expected string, got null");
                                    }

                                    if (args != null)
                                    {
                                        var count = 0;
                                        while (true)
                                        {
                                            using (var value = args[count + 1]) {
                                                if (value is LuaNil)
                                                {
                                                    break;
                                                }
                                                if (!(value is IClrObject))
                                                {
                                                    throw new LuaException($"args: Expected entry at index {count} to be a CLR Type object, got non-CLR object of type {value.GetType()}");
                                                }
                                                else if (!(((IClrObject)value).ClrObject is Type))
                                                {
                                                    throw new LuaException($"args: Expected entry at index {count} to be a CLR Type object, got CLR object of type {((IClrObject)value).ClrObject.GetType()}");
                                                }
                                            }
                                            count += 1;
                                        }

                                        var argtypes = new Type[args.Count];

                                        for (int i = 1; i <= count; i++)
                                        {
                                            using (var value = args[i]) {
                                                argtypes[i - 1] = (Type)args[i].CLRMappedObject;
                                            }
                                        }

                                        criteria_argtypes = argtypes;
                                    }

                                    criteria_instance   = instance?.ToBoolean() ?? true;
                                    criteria_public     = @public?.ToBoolean() ?? true;
                                    criteria_methodname = method.ToString();

                                    hook_returns = returns?.ToBoolean() ?? false;
                                }
            }

            var method_info = _TryFindMethod(
                criteria_type,
                criteria_methodname,
                criteria_argtypes,
                criteria_instance,
                criteria_public
                );

            if (method_info == null)
            {
                throw new LuaException($"Method '{criteria_methodname}' in '{criteria_type.FullName}' not found.");
            }

            RuntimeHooks.InstallDispatchHandler(method_info);

            var token = RuntimeHooks.MethodToken(method_info);

            _Hooks[token] = fn;
            fn.DisposeAfterManagedCall = false;

            if (hook_returns)
            {
                _HookReturns[token] = method_info.ReturnType;
            }

            _Logger.Debug($"Added Lua hook for method '{criteria_methodname}' ({token})");
        }