ParserLib Documentation

## Table of Contents

### Introduction

### Supported Events

### How to use

### Example

### Optimizer

### API

### Variable Description

#### Introduction

ParserLib is an embedded library which does all the combat message parsing and converting them into meaningful information.
To use ParserLib, your addon register events to ParserLib like this:

    local parser = ParserLib:GetInstance("1.1')
    parser:RegisterEvent("MyAddon", "CHAT_MSG_COMBAT_SELF_HIT", "MyAddonEventHandler")

Very similar to what you do to frame:RegisterEvent(), when the registered event is fired, ParserLib will call your registered handler, but instead of arg1, it passes a table as the second parameter:

    function MyAddonEventHandler(event, info)
     if info.type == "hit" then ChatFrame1:AddMessage( info.source .. " hit " .. info.victim .. " for " .. info.damount .. "damage!" ) end
    end

All ParserLib do is convert the arg1 into a table, for now you'll still need to know which event to register.
So what's the benefits for using ParserLib?

- By dynamically sorting the patterns in a special way, ParserLib works on all localizations. No worrying about:

- "Greater Heal critically" being parsed as spell name for "Your %s heals you for %d."
- "you" being parsed as victim name for "%s hits %s for %s."
- "30 mana from Someone's Blessing of Wisdom" being parsed as buff name for "%s gains %s."

- Minimal memory usage, if you don't register any event then almost only the raw codes are loaded.

- Multiple client addons share the same instance of ParserLib.

- Only listen to an event when a client registers for it.

- Load event-pattern list only when the event is actually fired.
- Load pattern table only when that pattern is required to parse.
- Recycles tables by using CompostLib.

- Better Efficiency

- ParserLib knows what event will fire what patterns, and only parse through the possible patterns.
- When there are multiple client addons, the patterns are only parsed once. Without using a common library, everyone will have to do their own parsing, which is a waste of resource.

Back to top

#### Supported Events

Click the link to see what patterns will be fired from the event.
(They''re still not very complete though, I'm working hard on it.)
Currently supported
Planned to support in the future
Won't be supported
Currently supported
CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS
CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES
CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS
CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES
CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS
CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES
CHAT_MSG_COMBAT_FACTION_CHANGE
CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS
CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES
CHAT_MSG_COMBAT_FRIENDLY_DEATH
CHAT_MSG_COMBAT_HONOR_GAIN
CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS
CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES
CHAT_MSG_COMBAT_HOSTILE_DEATH
CHAT_MSG_COMBAT_PARTY_HITS
CHAT_MSG_COMBAT_PARTY_MISSES
CHAT_MSG_COMBAT_PET_HITS
CHAT_MSG_COMBAT_PET_MISSES
CHAT_MSG_COMBAT_SELF_HITS
CHAT_MSG_COMBAT_SELF_MISSES
CHAT_MSG_COMBAT_XP_GAIN
CHAT_MSG_SPELL_AURA_GONE_OTHER
CHAT_MSG_SPELL_AURA_GONE_SELF
CHAT_MSG_SPELL_AURA_GONE_PARTY
CHAT_MSG_SPELL_BREAK_AURA
CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF
CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE
CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF
CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE
CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF
CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE
CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS
CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF
CHAT_MSG_SPELL_FAILED_LOCALPLAYER
CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF
CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE
CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF
CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE
CHAT_MSG_SPELL_ITEM_ENCHANTMENTS
CHAT_MSG_SPELL_PARTY_BUFF
CHAT_MSG_SPELL_PARTY_DAMAGE
CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS
CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE
CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS
CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE
CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS
CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE
CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS
CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE
CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS
CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE
CHAT_MSG_SPELL_PET_BUFF
CHAT_MSG_SPELL_PET_DAMAGE
CHAT_MSG_SPELL_SELF_BUFF
CHAT_MSG_SPELL_SELF_DAMAGE
CHAT_MSG_SPELL_TRADESKILLS
Planned to support in the future
CHAT_MSG_COMBAT_MISC_INFO
CHAT_MSG_SKILL
CHAT_MSG_LOOT
Won't be supported
CHAT_MSG
CHAT_MSG_AFK
CHAT_MSG_BG_SYSTEM_ALLIANCE
CHAT_MSG_BG_SYSTEM_HORDE
CHAT_MSG_BG_SYSTEM_NEUTRAL
CHAT_MSG_CHANNEL
CHAT_MSG_CHANNEL_JOIN
CHAT_MSG_CHANNEL_LEAVE
CHAT_MSG_CHANNEL_LIST
CHAT_MSG_CHANNEL_NOTICE
CHAT_MSG_CHANNEL_NOTICE_USER
CHAT_MSG_COMBAT_ERROR
CHAT_MSG_DND
CHAT_MSG_EMOTE
CHAT_MSG_GUILD
CHAT_MSG_IGNORED
CHAT_MSG_MONSTER_EMOTE
CHAT_MSG_MONSTER_SAY
CHAT_MSG_MONSTER_WHISPER
CHAT_MSG_MONSTER_YELL
CHAT_MSG_OFFICER
CHAT_MSG_PARTY
CHAT_MSG_RAID
CHAT_MSG_SAY
CHAT_MSG_SYSTEM
CHAT_MSG_TEXT_EMOTE
CHAT_MSG_WHISPER
CHAT_MSG_WHISPER_INFORM
CHAT_MSG_YELL
Back to top

#### How To Use

1. Put both CompostLib and ParserLib folder in your addon.
2. Add CompostLib and ParserLib to .toc so it looks like this:

    	## Interface: 11000
    	## Title: MyAddOn
    	## Notes: A ParserLib client addon.
    	CompostLib\CompostLib.lua
    	ParserLib\ParserLib.lua
    	SimpleCombatLog.xml

3. In your lua file, get an instance of ParserLib by calling the ParserLib:GetInstance() method.

    	local parser = ParserLib:GetInstance("1.1")

Where the "1.1" is the major version number (variable vmajor) which can be found at the top of ParserLib.lua
4. To listen to an event, do not Frame:RegisterEvent(), instead register the events to ParserLib:

    	parser:RegisterEvent("MyAddOn", "CHAT_MSG_COMBAT_SELF_HITS", "MyAddOn_OnParserEvent")

5. Now define your event handler, ParserLib will call it when the registered event occurs.

    	function MyAddOn_OnParserEvent(event, info)
    	-- check info.type to know what's inside info.
    	-- do whatever you want with the data.
    	end

6. info is a table which contains parsed information. To know what information you can get from the table, check the info.type variable, detailed description for each type is here.
NOTE: ParserLib recycles the info table to reduce memory usage, if you want to do something with the table after the event handler, make sure you store them in your own data structure.
Let me say it again, the info table will be CLEARED after the event handler has finished.

### YOU ARE EXPECTED TO COPY DOWN THE VARIABLES YOU NEED BEFORE THE END OF YOUR EVENT HANDLER.

Back to top

#### Example

    	function MyAddOn_OnParserEvent(event, info)
    	if info.type == "hit" then
    	if info.source == ParserLib_SELF then info.source = "you" end
    	if info.victim == ParserLib_SELF then info.source = "you" end
    	if info.skill == ParserLib_MELEE then info.skill = "melee" end
    	ChatFrame1:AddMessage(info.source .. " hits " .. info.victim .. " with " .. info.skill .. " for " .. info.amount)
    	end
    	end

    	parser = ParserLib:GetInstance("1.1")
    	parser:AddEventHandler("MyAddOn", "CHAT_MSG_COMBAT_SELF_HITS", "MyAddOn_OnParserEvent")
    	parser:AddEventHandler("MyAddOn", "CHAT_MSG_COMBAT_PET_HITS", "MyAddOn_OnParserEvent")
    	parser:AddEventHandler("MyAddOn", "CHAT_MSG_SPELL_SELF_DAMAGE", "MyAddOn_OnParserEvent")
    	parser:AddEventHandler("MyAddOn", "CHAT_MSG_SPELL_PET_DAMAGE", "MyAddOn_OnParserEvent")
    	parser:AddEventHandler("MyAddOn", "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE", "MyAddOn_OnParserEvent")
    	parser:AddEventHandler("MyAddOn", "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE", "MyAddOn_OnParserEvent")

Now you got yourself an addon which will report melee and spell hits of you and your pet!
Back to top

#### Optimizer

ParserLib currently includes a file called optimizer-enUS.lua, it can increase the parsing speed of ParserLib by around 20~30% on english locaization. By looking at the source code of optimizer-enUS.lua, you can easily create an optimizer file for other localizations. Basically the optimizer is simply a table which contains 'keyword string' for the patterns in WoW. For example the keyword 'hit' in COMBATHITSCHOOLOTHEROTHER (%s hits %s for %d %s damage.). The optimizer is completely optional, ParserLib works fine without any optimizer, just that the existance of an optimizer for your localization can increase the parsing speed.
To load an optimizer, simply include that file on your .toc, so it looks like this:

    	## Interface: 11000
    	## Title: MyAddOn
    	## Notes: A ParserLib client addon.
    	CompostLib\CompostLib.lua
    	ParserLib\ParserLib.lua
    	ParserLib\optimizer-enUS.lua
    	SimpleCombatLog.xml

Note that the optimizer is global, which means if someone added an optimizer table which has the wrong keyword, it could mess out ParserLib which will affect all the ParserLib clients. This is not good so this part will probably get reworked, for now I suggest you don't try to add your own optimizer file, but optimizer-enUS.lua should work fine.
Back to top

#### API

- RegisterEvent(addonID, event, handler) : Register an event with the event handler.

- UnregisterEvent(addonID, event) : Unregister an event for the addonID.

- UnregisterAllEvents(addonID) : Unregister all events for the addonID.

- Deformat(text, pattern) : Use this to parse for custom patterns which is not supported by ParserLib.

    	attacker, victim, amount, element = parser:Deformat("Rophy hits Pig for 500 fire damage.", COMBATHITSCHOOLOTHEROTHER)

Back to top

#### Variable Description

The table passed to your event handler will always contains a variable called type, which you can check to know what other variables are stored in the table.
'type' is one of the following strings:

hit | heal | miss | death | debuff
buff | fade | cast | dispel | extraattack
gain | drain | leech | interrupt | fail
environment | honor | experience | reputation | feedpet
enchant | create | durability |  |

Back to top
Normally all the variables are string tokens parsed from the combat message, with a few exceptions:

- source, victim, sourceGained might be a numeric constant ParserLib_SELF, which means it's you.
- skill might be the numeric constant ParserLib_MELEE for melee, or ParserLib_DAMAGESHIELD for damage shields.
- amount and its variations (amountGained, amountRaidPenality etc ) are numbers.
- missType is one of the following strings: miss, dodge, block, deflect, immune, evade, parry, resist, reflect, absorb
- damageType is one of the following strings: drown, fall, exhaust, fire, lava, slime.
- Variables starting with is are booleans, for example isDOT, isCrit, isItem etc.

Here is the list of all possible type, with the variables associated with them, a starting @ means that variable may not exist, depends on the combat message parsed.
The list is in the following format:

    TYPE : simple description.
    * example combat message.
    	Variable : value
    	@OptionalVariable : value

hit : including melee/spell/skill hits, crits, dots.
* Your Shadow Bolt crits Pig for 50 shadow damage. (30 resisted)
source : ParserLib_YOU
victim : "Pig"
skill : "Shadow Bolt"
amount : 50
@element : "shadow"
isCrit : true
isDOT : false
isCrushing : false
isGlancing : false
@amountAbsorb : nil
@amountBlock : nil
@amountResist : 30
@amountVulnerable : nil
Back to list
heal : including heals and HoTs.
* You gains 50 health from Priest's Renew.
source : "Priest"
victim : ParserLib_YOU
skill : "Renew"
amount : 50
isCrit : false
isDOT : true
Back to list
miss : Including miss, dodge, block, deflect, immune, evade, parry, resist, reflect, absorb.
* Warrior's Overpower was parried by Flamewaker.
source : "Warrior"
victim : "Flamewaker"
skill : "Overpower"
missType : "parry" (This is a fixed string, not parsed)
Back to list
death
* Rophy is slain by Bigpotato!
victim : "Rophy"
@source : "Bigpotato"
isItem : nil
* Magma Totem IV is destroyed.
victim : "Magma Totem IV"
@source : nil
isItem : true
Back to list
debuff
* Peter is afflicted by Shadow Vulnerability (2).
victim : "Peter"
skill : "Shadow Vulnerability"
@amountRank : 2
Back to list
buff
* Rophy gains Power Word: Shield.
victim : "Rophy"
skill : "Power Word: Shield"
@amountRank : nil
Back to list
fade : this might be buff or debuff, can't be distinguished by the message.
* Cheap Shot fades from Alterac Ram.
victim : "Alterac Ram"
skill : "Cheap Shot"
Back to list
cast : note that this includes "cast" and "perform".
* Doggy casts Growl on Mirefin Oracle.
source : "Doggy"
skill : "Growl"
@victim : "Mirefin Oracle"
isBegin : nil <- only one will exist between isBegin and victim.
isPerform : nil
* Rophy performs Opening on Onyxia's Gate.
source : "Rophy"
skill : "Opening"
@victim : "Onyxia's Gate"
isBegin : nil
isPerform : true
* Stormpike Mountaineer begins to perform Shoot.
source : "Stormpike Mountaineer"
skill : "Shoot"
@victim : nil
isBegin : true
isPerform : true
Back to list
gain
* You gain 10 Mana from Pally's Blessing of Wisdom.
source : "Pally"
victim : ParserLib_YOU
skill : "Blessing of Wisdim"
amount : 10
attribute : "Mana"
Back to list
drain
* Hunter's Viper Sting drains 277 Mana from Priest.
source : "Hunter"
victim : "Priest"
skill : "Viper Sting"
amount : 277
attribute : "Mana"
Back to list
leech
* Your Drain Mana drains 140 Mana from Mage. You gain 140 Mana.
source : ParserLib_YOU
victim : "Mage"
skill : "Drain Mana"
amount : 140
attribute : "Mana"
sourceGained: ParserLib_YOU
amountGained: 140
attributeGained: "Mana"
Back to list
dispel : There are two kinds of message so I'll show two examples here.
* Seasoned Guardian's Sap is removed.
victim : "Seasoned Guardian"
skill "Sap"
isFailed : false
@source : nil
* Nino fails to dispel Librabear's Gehennas' Curse.
victim : "Librabear"
skill : "Gehennas' Curse"
isFailed : true
@source : "Nino"
Back to list
extraattack
* Rophy gains 2 extra attacks through Windfury Attack.
victim : "Rophy"
skill : "Windfury Attack"
amount : 2
Back to list
environment : falling, fire, lava dmg etc
* Rophy suffers 468 points of fire damage. (298 absorbed)
victim : "Rophy"
amount : 468
damageType : "fire"
@amountAbsorb : 298
@amountBlock : nil
@amountResist : nil
@amountVulnerable : nil
Back to list
honor : Two examples here.
* You have been awarded 198 honor points.
@amount : 198
@source : nil
@sourceRank : nil
isDishonor : nil
* Nino dies, honorable kill Rank: Stone Guard (Estimated Honor Points: 80)
@amount : 80
@source : "Nino"
@sourceRank : "Stone Guard" <-- if source exists then sourceRank exists too.
isDishonor : nil
* Someone dies, dishonorable kill.
@amount : nil
@source : "Someone"
@sourceRank nil
isDishonor : true <-- amount is nil if and only if isDishonor is true,
Back to list
experience : This one is complicated, most of the time you just need to look for amount though.
* Mob dies, you gain 300 experience. (+160 exp Rested bonus, -20 raid penalty)
amount : 300
@source : "Mob"
@victim : nil <- if nil then it's you who got the exp.
@bonusAmount : "+160" <- Note that this is a string with '+', not a number.
@bonusType : "Rested" <- if bonusAmount exists then this exists too.
@penaltyAmount : nil
@penaltyType : nil
@amountRaidPenalty : 20
@amountGroupBonus : nil
* Someone gains 200 experience.
amount : 200
@victim : "Someone"
(all others are nil)
(This is the only pattern which has a victim, I have never seen it, but it exists anyway.)
Note: the message of exp gained by discovering an area is fired by CHAT_MSG_SYSTEM, which will NOT be supported by ParserLib.
Back to list
reputation
* Your reputation with Undercity has slightly increased. (50 reputation gained)
faction : "Undercity"
@amount : 50 <- if amount exists then rank is nil.
@rank : nil
isNegative : nil <- make sure you check this.
* You are now Friendly with Steamwheedle Cartel.
faction : "Steamwheedle Cartel"
@amount : nil
@rank : "Friendly" <- if rank exists then amount is nil.
isNegative : nil
Back to list
feedpet
* Hunter's pet begins eating a Moist Cornbread.
victim : "Hunter"
item : "Moist Cornbread"
Back to list
enchant
* Rophy casts Scope (+7 Damage) on Mondain's Precisely Calibrated Boomstick.
source : "Rophy"
victim : "Mondain"
skill : "Scope (+7 Damage)"
item : "Precisely Calibrated Boomstick"
Back to list
fail
* You fail to cast Immune Charm/Fear/Polymorph: Item is not ready yet.
source : ParserLib_SELF
skill : "Immune Charm/Fear/Polymorph"
reason : "Item is not ready yet"
Back to list
interrupt
* Bigpotato interrupts Scholomance Neophyte's Shadow Bolt.
source : "Bigpotato"
victim : "Scholomance Neophyte"
skill : "Shadow Bolt"
Back to list
create
* You create Blinding Powder.
source : ParserLib_SELF
item : "Blinding Powder"
Back to list
durability
* Ragnaros casts Melt Weapon on Dragonx: Bloodlord's Defender damaged.
source : "Ragnaros"
skill : "Melt Weapon"
victim : ParserLib_SELF
@item: "Bloodlord's Defender"
isAllItems : false <- if isAllItems true then item will be nil
Back to list