Lua-创建插曲的函数

我需要对不同的函数进行多次绕路,逐个进行操作根本不现实。我正在寻找一个函数,最好可以使用一个类传递一个表格,并循环访问该表格。对于每个函数键值对,生成一个带有前缀的函数指针。我已经尝试过好几个变化来实现这个效果,但是都会产生不同的问题。一些函数即使您提供任何东西都不会产生绕路指针,其他一些函数可能会产生绕路指针,但是它们不起作用,有些可能会溢出堆栈,或者根本不会被识别。

我想知道是否有一种方法,即使用rawsets、metatable覆盖、不断循环直到它们匹配等方法,使函数能够获得一个表格(或具有与表格相同名称的字符串,因此在此处可以使用loadstring方法)并循环访问每个函数并生成有效的绕路指针...无论如何。

我更喜欢使用self:prefix_orig_name(...)语法[...可以替换为实际参数]。

下面是我尝试的两种变体以及示例用法。

-- 第一种方法
detours = detours or {}

function detour(object, class) -- Class是一个额外的参数,如果只发送对象没用,就会发生这种情况,这是一个理论上的方法
    if detours[object] then -- 检查是否已经存在绕路...可能值得重新制作它,特别是如果该函数在不同的地方被覆盖了好几次?
        print("detour: Previous " .. object .. " detour found, using previous detour")
        return
    end
    for name, func in pairs(class and class or loadstring("return " .. object)()) do
        -- 这里使用loadstring方法是因为接收到的参数是与表格名称相同的字符串...因此加载它将产生一个表格
        if type(func) == "function" then
            local execute, error = loadstring(object .. ".custom_detour_" .. name .. " = " .. object .. "." .. name) -- 这会生成实际的指针
            if error then
                print("detour Error: " .. " Failed to detour: " .. object .. " Error: " .. error)
            end
            local luanch, assert = pcall(execute)
            if not luanch then
                print("detour Error: " .. " Failed to detour: " .. object .. " Error: " .. assert)
            end
        end
    end
    print("Table: " .. object .. " successfully detourd")
    detours[object] = true -- 告诉我们我们对这个表格/字符串进行了修改
end

-- 第二种方法
function detour(object) -- 接受表格
    for k, v in pairs(object) do
        if type(v) == "function" and not detours[k] then
            if not object.custom_detour_ then
                object.custom_detour_ = clone(object) -- 使用一个简单的克隆函数(浅克隆)将主表克隆到主表的子表中
            end
            if object["custom_detour_" .. k] ~= object.custom_detour_[k] then
                object["custom_detour_" .. k] = object.custom_detour_[k] -- 这样就可以使用 self:custom_detour_orig_name(...) 语法了,如果我没有弄错的话
            end
        end
    end
end

-- 示例用法:
MyClass = class() -- 类函数通常是面向对象的

function MyClass:init()
    self._something = true
end

function MyClass:change(value)
    self._something = value
end

function MyClass:table_print(tbl) -- 只是随意编造一些函数
    for k, v in pairs(tbl) do
        print(v)
    end
end

my_class = MyClass:new()

-- 第一种方法
detour("MyClass")

--第二种方法
detour(MyClass)

我个人更喜欢第一种方法或至少使用字符串,因为我可以记录每个绕路,如果以后出现问题,这将使调试更加容易...但无论哪种方法都可以。

点赞
用户646619
用户646619

使用闭包很容易进行简单的绕路;不需要使用 loadstring

function detour(cls)
    local detours = {}
    for key, value in pairs(cls) do
        if type(value) == "function" then -- 注意:忽略具有 __call 元方法的对象
            detours["custom_detour_"..key] = function(...)
                -- 在此执行你想要的操作
                return value(...)
            end
        end
    end
    for key, value in pairs(detours) do
        cls[key] = value
    end
end
2015-06-05 01:17:12