尝试调用全局变量 'this'(一个空值)

我可以看到类似的问题已经被问过了,但是我对 lua 编程不是很熟悉。 我正在尝试修复一个旧的魔兽世界经典版本插件,使其能在 Classic 客户端中运行。

代码如下:

    function FHH_OnLoad()

    this:RegisterEvent("PLAYER_ENTERING_WORLD");
    this:RegisterEvent("UPDATE_MOUSEOVER_UNIT");

    -- 注册斜杠命令
    SLASH_FHH1 = "/huntershelper";
    SLASH_FHH2 = "/hh";
    SlashCmdList["FHH"] = function(msg)
        FHH_ChatCommandHandler(msg);
    end

    local version = GetAddOnMetadata("GFW_HuntersHelper", "Version");
    GFWUtils.Print("Fizzwidget Hunter's Helper "..version.." 初始化!");

end

并且它抛出以下错误;

Message: Interface\AddOns\GFW_HuntersHelper\HuntersHelper.lua:27: attempt to index global 'this' (a nil value)
Time: Tue Jun 30 09:25:14 2020
Count: 1
Stack: Interface\AddOns\GFW_HuntersHelper\HuntersHelper.lua:27: attempt to index global 'this' (a nil value)
Interface\AddOns\GFW_HuntersHelper\HuntersHelper.lua:27: in function `FHH_OnLoad'
[string "*:OnLoad"]:1: in function <[string "*:OnLoad"]:1>

Locals: (*temporary) = nil
(*temporary) = nil
(*temporary) = nil
(*temporary) = nil
(*temporary) = nil
(*temporary) = "尝试对全局变量 'this'(一个 nil 值)进行索引"

我已经尝试过更改 "this" 语句,但我不是很确定该怎么做,所以想看看这里聪明的人是否知道发生了什么。

点赞
用户4567755
用户4567755

如果要找的插件相当老,那么在过去的某个时间(2010年?),Addon API已经从全局变量转移到了局部变量。

框架在 XML 文件中定义,就像您在评论中发表的这样:

<Frame name="HuntersHelperFrame">
   <Scripts>
      <OnLoad>FHH_OnLoad();</OnLoad>
      <OnEvent>
         FHH_OnEvent(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
      </OnEvent>
   </Scripts>
</Frame>

<Scripts> 中的元素实际上被称为函数,其内容为函数体。它们带有 一些 参数进行调用。使用《魔兽世界 API》作为参考可以发现这些参数是 _什么_。虽然不是官方的,但这是最接近参考手册的东西。

现在,您应该关注小部件处理程序

那么,您应该采取的第一步是:

  1. 更改 XML:

    <Frame name="HuntersHelperFrame">
       <Scripts>
          <OnLoad>FHH_OnLoad(self)</OnLoad>
          <OnEvent>
             FHH_OnEvent(self, event, ...)
          </OnEvent>
       </Scripts>
    </Frame>
    
  2. 更改 lua 以反映这一点:

    function FHH_OnLoad(self)
       self:RegisterEvent("PLAYER_ENTERING_WORLD")
       -- 等等,将所有 ‘this’ 更改为 ‘self’
       -- 或者只是将第一个参数命名为 ‘this’ 而不是 ‘self’:
       -- function FHH_OnLoad(this)
    end
    
    -- 更改所有函数:
    function FHH_OnEvent(self, event, ...)
       -- 函数体
    end
    

根据插件的大小,可能需要花费大量工作。不幸的是,这还没有结束;请注意,脚本可能直接依赖于全局变量的存在并进行一些技巧。

我猜您可以尝试使用类似 local this = self 的技巧进行工作,但这可能不适用于所有情况,并且由于框架可能解析 XML 的方式而导致一些问题。

最后一点提示;API 多年来发生了很大的变化,您很可能会遇到更多问题。祝您好运!

2020-06-30 13:32:50