WoW:Parsing event messages: Difference between revisions

From AddOn Studio
Jump to navigation Jump to search
No edit summary
Line 62: Line 62:
Harnessing this information yourself can be quite a task.  You need to revise your code to look at this variable, transform the value of this variable into a value suitable for your pattern variable, run your pattern, and then be able to reorder the parameters correctly based on the value of this variable.
Harnessing this information yourself can be quite a task.  You need to revise your code to look at this variable, transform the value of this variable into a value suitable for your pattern variable, run your pattern, and then be able to reorder the parameters correctly based on the value of this variable.


However, each AddOn author should not have to do nearly this much work.  There's a library called MarsMessageParser.  I don't have a link to that file directly, but you will find it as a separate file inside of [[http://www.curse-gaming.com/mod.php?addid=2275 this AddOn]].  You can copy MarsMessageParser.lua out of there and put it in your AddOn, say MyHonorTracker.  Make sure MarsMessageParser.lua is listed before MyHonorTracker.lua in your MyHonorTracker.toc file or your MyHonorTracker.xml file.  Then, all of the above code can be trimmed down to just this:
However, each AddOn author should not have to do nearly this much work.  There's a library called MarsMessageParser.  I don't have a link to that file directly, but you will find it as a separate file inside of [[http://ui.worldofwar.net/ui.php?id=291 this AddOn]].  You can copy MarsMessageParser.lua out of MarsNeedyGreedy and put it in your AddOn, say MyHonorTracker.  Make sure MarsMessageParser.lua is listed before MyHonorTracker.lua in your MyHonorTracker.toc file or your MyHonorTracker.xml file.  Then, all of the above code can be trimmed down to just this:


  function MyHonorTracker_OnEvent()
  function MyHonorTracker_OnEvent()

Revision as of 02:43, 21 December 2006

What are event messages?

Event messages are things like combat log messages, loot messages, online/offline notifications, and so on.

Why would I want to parse event messages?

If you are writing an AddOn that wants to take some sort of action when a certain event happens (for example, tracking your honor from PvP kills), you need to find the correct event and register to listen for that event. Some events provide you the information about that event in compact easy-to-use arguments. For example, the REPLACE_ENCHANT event has two arguments, arg1 (the name of the enchant) and arg2 (the name of the item). Other events don't provide you the arguments in such an easy-to-use form. For example, the CHAT_MSG_COMBAT_HONOR_GAIN event has one big long argument, arg1, that looks something like "Joe dies, honorable kill Rank: Commander (Estimated Honor Points: 10)". What you really want to know, though, is

  1. who died
  2. what their rank was, and
  3. how many estimated honor points it was worth.

In order to get this information, you need to parse the big long string.

What's the quick-and-dirty way to parse an event message?

Well, you can look at how the event message looks, and you can manually write a string.find over that string to extract the information you need. For example,

function MyHonorTracker_OnEvent()
  if(event == "CHAT_MSG_COMBAT_HONOR_GAIN") then
    start, end, killed, rank, honor =
      string.find(arg1, "(.+) dies, honorable kill Rank: (.+) %(Estimated Honor Points: (.+)%)");
    if(start) then
      MyHonorTrackingFunction(killed, rank, honor);
    end
  end
end

What's so dirty about the quick-and-dirty way?

You will find that as people in other locales start using your AddOn, that they have problems. This is due to the fact that your code is expecting the system messages to be arriving in English, whereas they might actually be arriving in some other language.

Once you've started off on the quick-and-dirty way, you are likely to consider asking people to provide you translations, so you can modify your code accordingly for a quick-and-dirty fix. However, you can tell what a mess your code would quickly turn into:

function MyHonorTracker_OnEvent()
  if(event == "CHAT_MSG_COMBAT_HONOR_GAIN") then
    if(GetLocale() == "enUS") then
      pattern = "(.+) dies, honorable kill Rank: (.+) %(Estimated Honor Points: (.+)%)";
    elseif(GetLocale() == "deDE") then
      pattern = "(.+) german-for-dies, german-words: (.+) %(more-german: (.+)%)";
    elseif(GetLocale() == "frFR") then
      pattern = "french-words (.+) french-words (.+) french-words (.+)";
      -- notice that the parameters are not necessarily always in the same order in all languages
    else
      pattern = "who knows";
    end
    start, end, param1, param2, param3 = string.find(arg1, pattern);
    if(GetLocale() == "frFR") then
      -- correct the order of the parameters
      killed, rank, honor = param2, param1, param3;
    else
      killed, rank, honor = param1, param2, param3;
    end
    if(start) then
      MyHonorTrackingFunction(killed, rank, honor);
    end
  end
end

What's the clean-and-easy way?

Well, first, you should extract GlobalStrings.lua out of your WoW install. Then, you will want to look through that file for the variable that contains the template of the message you're looking for. In our case, it is

COMBATLOG_HONORGAIN = "%s dies, honorable kill Rank: %s (Estimated Honor Points: %d)";

This variable is the key to this method. Basically, Blizzard has already done the work of creating translations for every language that WoW supports, and they have provided this GlobalStrings.lua to map those translations to common variable names. We just need to figure out how to harness this information.

Harnessing this information yourself can be quite a task. You need to revise your code to look at this variable, transform the value of this variable into a value suitable for your pattern variable, run your pattern, and then be able to reorder the parameters correctly based on the value of this variable.

However, each AddOn author should not have to do nearly this much work. There's a library called MarsMessageParser. I don't have a link to that file directly, but you will find it as a separate file inside of [this AddOn]. You can copy MarsMessageParser.lua out of MarsNeedyGreedy and put it in your AddOn, say MyHonorTracker. Make sure MarsMessageParser.lua is listed before MyHonorTracker.lua in your MyHonorTracker.toc file or your MyHonorTracker.xml file. Then, all of the above code can be trimmed down to just this:

function MyHonorTracker_OnEvent()
  if(event == "CHAT_MSG_COMBAT_HONOR_GAIN") then
    MarsMessageParser_ParseMessage("MyHonorTracker", arg1);
  end
end

Well, that isn't exactly true: MarsMessageParser also needs to be initialized. Fortunately, this can be done with just one line (put this line somewhere in your initialization area):

MarsMessageParser_RegisterFunction("MyHonorTracker", COMBATLOG_HONORGAIN, MyHonorTrackingFunction);

The parameters to the RegisterFunction function are as follows:

  1. The first parameter is your AddOn name and needs to match the name you pass in to the ParseMessage function.
  2. The second parameter is the name of the template variable from GlobalStrings.lua for the message you want to parse.
  3. The third parameter is the function you want called with the parameters extracted from the event messages.
  4. An optional fourth parameter (not shown) specifies how MarsMessageParser should handle item links if they are present (either collapsing them or leaving them in pieces). Since there are no items links in an honor function, we omit the fourth parameter. For more details, see the API description at the top of MarsMessageParser.lua.

The parameters to the ParseMessage function are as follows:

  1. The first parameter is your AddOn name and needs to match the name you passed in to the RegisterFunction function.
  2. The second parameter is the big long string you got from WoW (typically arg1).

MarsMessageParser will take care of reading the GlobalStrings.lua, creating the correct pattern for the current locale, re-ordering the parameters accordingly, and finally calling MyHonorTrackingFunction with three parameters: killed, rank, and honor.