WoWInterface (
-   Lua/XML Help (
-   -   How can i hook complex Blizz functions, like: Module:FuncName(arguments)? (

Nikita S. Doroshenko 10-03-15 06:00 PM

How can i hook complex Blizz functions, like: Module:FuncName(arguments)?
I would like to SetJustifyH "CENTER" all ObjectiveTrackerBlocks and remove all "Dashes" as well. I'm talking about Blocks that contains information about Quests you currently track:
(Sorry for different language on screenshot)

Files that respond to this frames locates in Interface\AddOns\Blizzard_ObjectiveTracker\ folder.
There are lots of files in this folder, but I think most relevant is this: Blizzard_ObjectiveTracker.lua (link to

There are lot's of complex functions that I had never worked before. For example:

Lua Code:
  1. function DEFAULT_OBJECTIVE_TRACKER_MODULE:SetHeader(block, text, animateReason)
  2.     block.module = self;
  3.     block.isHeader = true;
  4.     block.Text:SetText(text);
  5.     block.animateReason = animateReason or 0;
  6.     self.Header = block;
  7. end

I tried to investigate more information about this functions and how they works, and for me (person who never programmed before, it's pretty hard to instantly understand them, but i would like).
On Hooking Functions Guide I read that it's possible to hook this strange functions. This Guide gives this example:
Lua Code:
  1. --[[Functions called using the object calling syntax, object:method(...), can also be hooked; one simply has to remember that the construct is merely syntactic sugar for object.method(object, ...);. To hook a function that was originally declared as:]]
  2. function AnAddon.Module:FuncName(arg1)
  3.   -- Things happen here...
  4. end
  5. --[[We store the original function and replace it with a hook:]]
  6. local original_AnAddon_Module_FuncName = AnAddon.Module.FuncName;
  7. function AnAddon.Module:FuncName(...)
  8.   local arg1 = ...; -- Use the vararg expression in case the function signature changes
  9.   if type(arg1) == "number" and arg1 > 0 then
  10.     -- Call the original function; because of object calling syntax,
  11.     --   pass self as the first argument.
  12.     return original_AnAddon_Module_FuncName(self, ...);
  13.   end
  14. end
  15. --[[The example hook above will only allow the original function to be called if the first argument is a strictly positive number.]]
According to this example, i tryed to hook Blizzards function "DEFAULT_OBJECTIVE_TRACKER_MODULE:SetHeader" with this code:

Lua Code:
  3.     print("TEST")
  5. end

But it looks like that i'm doing something wrong. I don't get any lua errors, but no print("TEST") as well, so it's not hooked.
I will very appreciate if you could help me with example of how can i hook this complex functions or with advice or ideas how can i SetJustifyH("CENTER") and remove Dash without hooking this crazy functions (Names of ObjectiveTrackerBlocks are dynamic: example on screenshot) :)

kurapica.igas 10-03-15 07:46 PM

SetHeader method is only used when Blizzard_ObjectiveTracker add-on is loaded, your function won't be call because your add-on can't be loaded before the Blizzard_ObjectiveTracker.

For secure, you should use hooksecurefunc. Maybe you can test on

Lua Code:

sticklord 10-03-15 08:13 PM

I'm not entirely sure, especially when it comes to metatables, but it seems like it stores the functions to the table DEFAULT_OBJECTIVE_TRACKER_MODULE and then creates a link to these with the metatable, so it still links to the old function in the memory if you dont hook it before the metatable is created. And it seems SetHeader is used only once per trackerframe on startup so I believe you cant hook it (theres a good chance Im wrong here though).

Maybe you can do something like this though


local trackers = {

for i,t in pairs(trackers) do

That is if it's the header you want to edit.

Phanx 10-03-15 08:27 PM

Based on the code used in Who Framed Watcher Wabbit this should probably work:

lua Code:
  1. -- Keep track of headers and lines we already processed:
  2. local skinnedHeaders, skinnedLines = {}, {}
  4. -- Function to apply changes to headers and lines:
  5. local function UpdateLine(module, block, objectiveKey, text, lineType, useFullHeight, hideDash, colorStyle)
  6.     -- Process the header:
  7.     local header = block.HeaderText
  8.     if header and not skinnedHeaders[header] then
  9.         -- Center align the header text:
  10.         header:SetJustifyH("CENTER")
  11.         -- (You can add more changes here if you like)
  12.         -- Add it to the table of headers we already processed:
  13.         skinnedHeaders[header] = true
  14.     end
  15.     -- Process the line itself:
  16.     local line = block.lines[objectiveKey]
  17.     if line and not skinnedLines[lines] then
  18.         -- Center align the line text:
  19.         line.Text:SetJustifyH("CENTER")
  20.         -- (You can add more changes here if you like)
  21.         -- If the line has a dash...
  22.         if line.Dash then
  23.             -- ...hide the dash:
  24.             line.Dash:Hide()
  25.             -- ...and prevent it from being shown in the future:
  26.             line.Dash.Show = line.Dash.Hide
  27.         end
  28.         -- Add it to the list of lines we already processed:
  29.         skinnedLines[line] = true
  30.     end
  31. end
  33. -- Hook the AddObjective method for all modules:
  34. for i = 1, #ObjectiveTrackerFrame.MODULES do
  35.     hooksecurefunc(ObjectiveTrackerFrame.MODULES[i], "AddObjective", UpdateLine)
  36. end
  37. hooksecurefunc(SCENARIO_TRACKER_MODULE, "AddObjective", UpdateLine)

Depending on how the lines are sized and anchored (I didn't look) you may need to make additional changes to support center alignment. If it doesn't look properly centered, post a screenshot.

All times are GMT -6. The time now is 08:55 PM.

vBulletin © 2020, Jelsoft Enterprises Ltd
© 2004 - 2020 MMOUI