vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 Name: ParserLib
3 Revision: $Revision: 11949 $
4 Author(s): rophy (rophy123@gmail.com)
5 Website: http://www.wowace.com/index.php/ParserLib
6 Documentation: http://www.wowace.com/index.php/ParserLib
7 SVN: http://svn.wowace.com/root/trunk/ParserLib
8 Description: An embedded combat log parser, which works on all localizations.
9 Dependencies: CompostLib (optional) or Compost-2.0 (optional).
10 ]]
11  
12 ---------------------------------------------------------------------------
13 -- To Get an instance of ParserLib, call this:
14 -- local parser = ParserLib:GetInstance(version)
15 -- where the version is the variable 'vmajor' you see here.
16 ---------------------------------------------------------------------------
17 local vmajor, vminor = "1.1", tonumber(string.sub("$Revision: 11949 $", 12, -3))
18  
19 local stubvarname = "TekLibStub"
20 local libvarname = "ParserLib"
21  
22 -- Check to see if an update is needed
23 -- if not then just return out now before we do anything
24 local libobj = getglobal(libvarname)
25 if libobj and not libobj:NeedsUpgraded(vmajor, vminor) then return end
26  
27  
28 ---------------------------------------------------------------------------
29 -- Embedded Library Registration Stub
30 -- Written by Iriel <iriel@vigilance-committee.org>
31 -- Version 0.1 - 2006-03-05
32 -- Modified by Tekkub <tekkub@gmail.com>
33 ---------------------------------------------------------------------------
34  
35 local stubobj = getglobal(stubvarname)
36 if not stubobj then
37 stubobj = {}
38 setglobal(stubvarname, stubobj)
39  
40 -- Instance replacement method, replace contents of old with that of new
41 function stubobj:ReplaceInstance(old, new)
42 for k,v in pairs(old) do old[k]=nil end
43 for k,v in pairs(new) do old[k]=v end
44 end
45  
46 -- Get a new copy of the stub
47 function stubobj:NewStub(name)
48 local newStub = {}
49 self:ReplaceInstance(newStub, self)
50 newStub.libName = name
51 newStub.lastVersion = ''
52 newStub.versions = {}
53 return newStub
54 end
55  
56  
57 -- Get instance version
58 function stubobj:NeedsUpgraded(vmajor, vminor)
59 local versionData = self.versions[vmajor]
60 if not versionData or versionData.minor < vminor then return true end
61 end
62  
63  
64 -- Get instance version
65 function stubobj:GetInstance(version)
66 if not version then version = self.lastVersion end
67 local versionData = self.versions[version]
68 if not versionData then print(string.format("<%s> Cannot find library version: %s", self.libName, version or "")) return end
69 return versionData.instance
70 end
71  
72  
73 -- Register new instance
74 function stubobj:Register(newInstance)
75 local version,minor = newInstance:GetLibraryVersion()
76 self.lastVersion = version
77 local versionData = self.versions[version]
78 if not versionData then
79 -- This one is new!
80 versionData = {
81 instance = newInstance,
82 minor = minor,
83 old = {},
84 }
85 self.versions[version] = versionData
86 newInstance:LibActivate(self)
87 return newInstance
88 end
89 -- This is an update
90 local oldInstance = versionData.instance
91 local oldList = versionData.old
92 versionData.instance = newInstance
93 versionData.minor = minor
94 local skipCopy = newInstance:LibActivate(self, oldInstance, oldList)
95 table.insert(oldList, oldInstance)
96 if not skipCopy then
97 for i, old in ipairs(oldList) do self:ReplaceInstance(old, newInstance) end
98 end
99 return newInstance
100 end
101 end
102  
103  
104 if not libobj then
105 libobj = stubobj:NewStub(libvarname)
106 setglobal(libvarname, libobj)
107 end
108  
109  
110 local lib = {}
111  
112  
113 -- Return the library's current version
114 function lib:GetLibraryVersion()
115 return vmajor, vminor
116 end
117  
118  
119 -- Activate a new instance of this library
120 function lib:LibActivate(stub, oldLib, oldList)
121 local maj, min = self:GetLibraryVersion()
122  
123 if oldLib then
124 local omaj, omin = oldLib:GetLibraryVersion()
125 ----------------------------------------------------
126 -- ********************************************** --
127 -- **** Copy over any old data you need here **** --
128 -- ********************************************** --
129 ----------------------------------------------------
130 self.frame = oldLib.frame
131 self:OnLoad()
132  
133 if omin < 11 and oldLib.clients then
134 for event in oldLib.clients do
135 for i in oldLib.clients[event] do
136 if type(oldLib.clients[event][i]["func"]) == "string" then
137 oldLib.clients[event][i]["func"] = getglobal(oldLib.clients[event][i]["func"])
138 end
139 end
140 end
141 end
142 self.clients = oldLib.clients
143  
144  
145 else
146 ---------------------------------------------------
147 -- ********************************************* --
148 -- **** Do any initialization you need here **** --
149 -- ********************************************* --
150 ---------------------------------------------------
151 self:OnLoad()
152 end
153 -- nil return makes stub do object copy
154 end
155  
156  
157  
158  
159  
160  
161  
162 ----------------------------------------------
163 -- *ParserLib Public Methods* --
164 ----------------------------------------------
165  
166 -- Register an event to ParserLib.
167 function lib:RegisterEvent(addonID, event, handler)
168  
169 local eventExist
170 for i, v in self.supportedEvents do
171 if v == event then
172 eventExist = true
173 break
174 end
175 end
176  
177 if not eventExist then
178 self:Print( string.format("Event %s is not supported. (AddOnID %s)", event, addonID), 1, 0, 0 )
179 return
180 end
181  
182  
183 -- self:Print(string.format("Registering %s for addon %s.", event, addonID) ); -- debug
184  
185 if type(handler) == "string" then handler = getglobal(handler) end
186  
187 -- if not handler then self:Print("nil handler from " .. addonID, 1, 0, 0) end -- debug
188  
189 if self.clients[event] == nil then
190 self.clients[event] = {};
191 end
192  
193 table.insert(self.clients[event], { ["id"]=addonID, ["func"]=handler } );
194 self.frame:RegisterEvent(event);
195  
196 end
197  
198 -- Check if you have registered an event.
199 function lib:IsEventRegistered(addonID, event)
200 if self.clients[event] then
201 for i, v in self.clients[event] do
202 if v.id == addonID then return true end
203 end
204 end
205 end
206  
207 -- Unregister an event.
208 function lib:UnregisterEvent(addonID, event)
209 local empty = true
210  
211  
212 if not self.clients[event] then return end
213  
214 for i, v in self.clients[event] do
215 if v.id == addonID then
216 -- self:Print( format("Removing %s from %s", v.id, event) ) -- debug
217 table.remove(self.clients[event], i)
218 else
219 empty = false
220 end
221 end
222  
223 if empty then
224 -- self:Print("Unregistering event " .. event) -- debug
225 self.frame:UnregisterEvent(event)
226 self.clients[event] = nil
227 end
228 end
229  
230 -- Unregister all events.
231 function lib:UnregisterAllEvents(addonID)
232 local event, index, empty;
233  
234 for event in self.clients do
235 empty = true;
236  
237 for i, v in self.clients[event] do
238 if v.id == addonID then
239 -- self:Print( format("Removing %s for %s", v.id, event) ) -- debug
240 table.remove(self.clients[event], i)
241 -- self.clients[event][index] = nil;
242 else
243 empty = false;
244 end
245 end
246  
247 if empty then
248 -- self:Print("Unregistering event " .. event) -- debug
249 self.frame:UnregisterEvent(event);
250 self.clients[event] = nil;
251 end
252  
253 end
254  
255 end
256  
257 -- Parse custom messages, check documentation.html for more info.
258 function lib:Deformat(text, pattern)
259 if not self.customPatterns then self.customPatterns = {} end
260 if not self.customPatterns[pattern] then
261 self.customPatterns[pattern] = self:Curry(pattern)
262 end
263 return self.customPatterns[pattern](text)
264 end
265  
266 --------------------------------------------------------
267 -- Methods to control ParserLib behaviour --
268 --------------------------------------------------------
269  
270 -- Use CompostLib or not?
271 -- Not that at 1.1-23 CompostLib no longer slows down the speed of ParserLib,
272 -- because I found out that I was calling CompostLib:Recycle too frequently, which can be avoided.
273 function lib:UseCompost(flag)
274 self.vars.noCompost = not flag
275 end
276  
277  
278 ---------------------------------------------------
279 -- *End of ParserLib Public Methods* --
280 ---------------------------------------------------
281  
282  
283 ----------------------------------------------
284 -- ParserLib Private Methods
285 ----------------------------------------------
286  
287 -- Constants
288 ParserLib_SELF = 103
289 ParserLib_MELEE = 112
290 ParserLib_DAMAGESHIELD = 113
291  
292 -- lib.timing = true -- timer
293  
294 -- Stub function called by frame.OnEvent
295 local function ParserOnEvent() lib:OnEvent() end
296  
297 -- Sort the pattern so that they can be parsed in a correct sequence, will only do once for each registered event.
298 local function PatternCompare(a, b)
299  
300 local pa = getglobal(a)
301 local pb = getglobal(b)
302  
303 if not pa then ChatFrame1:AddMessage("|cffff0000Nil pattern: ".. a.."|r") end
304 if not pb then ChatFrame1:AddMessage("|cffff0000Nil pattern: ".. b.."|r") end
305  
306 local ca=0
307 for _ in string.gfind(pa, "%%%d?%$?[sd]") do ca=ca+1 end
308 local cb=0
309 for _ in string.gfind(pb, "%%%d?%$?[sd]") do cb=cb+1 end
310  
311 pa = string.gsub(pa, "%%%d?%$?[sd]", "")
312 pb = string.gsub(pb, "%%%d?%$?[sd]", "")
313  
314 if string.len(pa) == string.len(pb) then
315 return ca < cb;
316 else
317 return string.len(pa) > string.len(pb)
318 end
319  
320 end
321  
322 local FindString = {
323 [0] = function(m,p,t) return string.find(m,p), t end,
324 [1] = function(m,p,t) _,_,t[1] = string.find(m,p) if t[1] then return true, t else return false, t end end,
325 [2] = function(m,p,t) _,_,t[1],t[2] = string.find(m,p) if t[2] then return true, t else return false, t end end,
326 [3] = function(m,p,t) _,_,t[1],t[2],t[3] = string.find(m,p) if t[3] then return true, t else return false, t end end,
327 [4] = function(m,p,t) _,_,t[1],t[2],t[3],t[4] = string.find(m,p) if t[4] then return true, t else return false, t end end,
328 [5] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5] = string.find(m,p) if t[5] then return true, t else return false, t end end,
329 [6] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5],t[6] = string.find(m,p) if t[6] then return true, t else return false, t end end,
330 [7] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5],t[6],t[7] = string.find(m,p) if t[7] then return true, t else return false, t end end,
331 [8] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8] = string.find(m,p) if t[8] then return true, t else return false, t end end,
332 [9] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9] = string.find(m,p) if t[9] then return true, t else return false, t end end,
333 }
334  
335 -- Currently supported event list.
336 lib.supportedEvents = {
337  
338 "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS",
339 "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES",
340 "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS",
341 "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES",
342 "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS",
343 "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES",
344 "CHAT_MSG_COMBAT_FACTION_CHANGE",
345 "CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
346 "CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
347 "CHAT_MSG_COMBAT_FRIENDLY_DEATH",
348 "CHAT_MSG_COMBAT_HONOR_GAIN",
349 "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS",
350 "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES",
351 "CHAT_MSG_COMBAT_HOSTILE_DEATH",
352 "CHAT_MSG_COMBAT_PARTY_HITS",
353 "CHAT_MSG_COMBAT_PARTY_MISSES",
354 "CHAT_MSG_COMBAT_PET_HITS",
355 "CHAT_MSG_COMBAT_PET_MISSES",
356 "CHAT_MSG_COMBAT_SELF_HITS",
357 "CHAT_MSG_COMBAT_SELF_MISSES",
358 "CHAT_MSG_COMBAT_XP_GAIN",
359 "CHAT_MSG_SPELL_AURA_GONE_OTHER",
360 "CHAT_MSG_SPELL_AURA_GONE_SELF",
361 "CHAT_MSG_SPELL_AURA_GONE_PARTY",
362 "CHAT_MSG_SPELL_BREAK_AURA",
363 "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF",
364 "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
365 "CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF",
366 "CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE",
367 "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF",
368 "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE",
369 "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS",
370 "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF",
371 "CHAT_MSG_SPELL_FAILED_LOCALPLAYER",
372 "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF",
373 "CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
374 "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF",
375 "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE",
376 "CHAT_MSG_SPELL_ITEM_ENCHANTMENTS",
377 "CHAT_MSG_SPELL_PARTY_BUFF",
378 "CHAT_MSG_SPELL_PARTY_DAMAGE",
379 "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS",
380 "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE",
381 "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS",
382 "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE",
383 "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS",
384 "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE",
385 "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS",
386 "CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE",
387 "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS",
388 "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE",
389 "CHAT_MSG_SPELL_PET_BUFF",
390 "CHAT_MSG_SPELL_PET_DAMAGE",
391 "CHAT_MSG_SPELL_SELF_BUFF",
392 "CHAT_MSG_SPELL_SELF_DAMAGE",
393 "CHAT_MSG_SPELL_TRADESKILLS",
394  
395 }
396  
397 function lib:GetCompost()
398  
399 if self.vars.noCompost then
400  
401 if not self.myCompost then
402 self.myCompost = {
403 Recycle = function() return {} end,
404 Acquire = function() return {} end,
405 Reclaim = function() end,
406 }
407 end
408 return self.myCompost
409  
410 else
411  
412 if not self.compost then
413 if AceLibrary and AceLibrary:HasInstance("Compost-2.0") then
414 self.compost = AceLibrary:GetInstance("Compost-2.0")
415 elseif CompostLib then
416 self.compost = CompostLib:GetInstance("compost-1")
417 else
418 -- Cannot find the existance of CompostLib
419 self.vars.noCompost = true
420 return self:GetCompost()
421 end
422 end
423 return self.compost
424  
425 end
426  
427 end
428  
429 -- Convert "%s hits %s for %d." to "(.+) hits (.+) for (%d+)."
430 -- Will additionaly return the sequence of tokens, for example:
431 -- "%2$s reflects %3$d %4$s damage to %1$s." will return:
432 -- "(.-) reflects (%+) (.-) damage to (.-)%.", 4 1 2 3.
433 -- ( [1]=2,[2]=3,[3]=4,[4]=1 Reverting indexes and become [1]=4, [2]=[1],[3]=2,[4]=3. )
434 function lib:ConvertPattern(pattern, anchor)
435  
436 local seq
437  
438 -- Add % to escape all magic characters used in LUA pattern matching, except $ and %
439 pattern = string.gsub(pattern,"([%^%(%)%.%[%]%*%+%-%?])","%%%1");
440  
441 -- Do these AFTER escaping the magic characters.
442 pattern = string.gsub(pattern,"%%s","(.-)"); -- %s to (.-)
443 pattern = string.gsub(pattern,"%%d","(%-?%%d+)"); -- %d to (%d+)
444  
445 if string.find(pattern,"%$") then
446 seq = {}; -- fills with ordered list of $s as they appear
447 local idx = 1; -- incremental index into field[]
448  
449 local tmpSeq = {}
450 for i in string.gfind(pattern,"%%(%d)%$.") do
451 tmpSeq[idx] = tonumber(i);
452 idx = idx + 1
453 end
454 for i, j in ipairs(tmpSeq) do
455 seq[j] = i
456 end
457 table.setn(seq, table.getn(tmpSeq))
458 pattern = string.gsub(pattern,"%%%d%$s","(.-)"); -- %1$s to (.-)
459 pattern = string.gsub(pattern,"%%%d%$d","(%-?%%d+)"); -- %1$d to (%d+)
460 end
461  
462 -- Escape $ now.
463 pattern = string.gsub(pattern,"%$","%%$");
464  
465 -- Anchor tag can improve string.find() performance by 100%.
466 if anchor then pattern = "^"..pattern end
467  
468 -- If the pattern ends with (.-), replace it with (.+), or the capsule will be lost.
469 if string.sub(pattern, -4) == "(.-)" then
470 pattern = string.sub(pattern, 0, -5) .. "(.+)";
471 end
472  
473 if not seq then return pattern end
474  
475 return pattern, seq[1], seq[2], seq[3], seq[4], seq[5], seq[6], seq[7], seq[8], seq[9], seq[10]
476 end
477  
478 function lib:OnLoad()
479  
480 -- Both table starts out empty, and load the data only when required.
481 self.eventTable = {}
482 self.patternTable = {}
483  
484  
485 self.vars = {}
486  
487 if self.timing then
488 self.timer = {
489 ParseMessage_LoadPatternList = 0,
490 ParseMessage_FindPattern = 0,
491 ParseMessage_FindPattern_Regexp = 0,
492 ParseMessage_FindPattern_Regexp_FindString = 0,
493 ParseMessage_FindPattern_LoadPatternInfo = 0,
494 ParseMessage_ParseInformation = 0,
495 ParseMessage_ParseTrailers = 0,
496 ParseMessage_ConvertTypes = 0,
497 NotifyClients = 0,
498 Compost_Acquire = 0,
499 Compost_Recycle = 0,
500 Compost_Reclaim = 0,
501 }
502 end
503  
504 if not self.clients then self.clients = {} end
505  
506 if not self.frame then
507 self.frame = CreateFrame("FRAME", "ParserLibFrame")
508 self.frame:SetScript("OnEvent", ParserOnEvent )
509 self.frame:Hide()
510 end
511  
512  
513 end
514  
515 function lib:OnEvent(e, a1)
516  
517 if not e then e = event end
518 if not a1 then a1 = arg1 end
519  
520 -- self:Print("Event: |cff3333ff"..e.."|r") -- debug
521  
522 -- Titan Honor+ was changing the global events... just change it back.
523 if e == "CHAT_MSG_HONORPLUS" then e = "CHAT_MSG_COMBAT_HONOR_GAIN" end
524  
525  
526 if self:ParseMessage(a1, e) then
527  
528 -- local timer = GetTime() -- timer
529 self:NotifyClients(e)
530 -- self.timer.NotifyClients = self.timer.NotifyClients + GetTime() - timer -- timer
531  
532 end
533  
534  
535 end
536  
537 function lib:NotifyClients(event)
538  
539 if not self.clients or not self.clients[event] then
540 -- self:Print(event .. " has no client to notify.") -- debug
541 return
542 end
543  
544 -- Noneed to recycle the table if there is only one client.
545 if table.getn(self.clients[event]) == 1 then
546 -- self:Print(event .. ", calling " .. self.clients[event][1].id) -- debug
547 self.clients[event][1].func(event, self.info)
548 return
549 end
550  
551 -- local timer = GetTime() -- timer
552 local info = self:GetCompost():Acquire()
553 -- self.timer.Compost_Acquire = GetTime() - timer + self.timer.Compost_Acquire -- timer
554  
555 for i, client in self.clients[event] do
556 -- self:Print(event .. ", calling " .. client.id) -- debug
557  
558 -- I can just do a compost:Recycle() here, but I hope this can improve the performance.
559 for j in info do if not self.info[j] then info[j] = nil end end
560 for j, v in self.info do info[j] = v end
561  
562 client.func(event, info)
563 end
564  
565 -- timer = GetTime() -- timer
566 self:GetCompost():Reclaim(info)
567 -- self.timer.reclaim = GetTime() - timer + self.timer.reclaim -- timer
568  
569 end
570  
571 function lib:Print(msg, r, g, b)
572 ChatFrame1:AddMessage(string.format("<%s-%s-%s> %s", libvarname, vmajor, vminor, msg), r, g, b)
573 end
574  
575  
576 -- message : the arg1 in the event
577 -- event : name says it all.
578 -- info : the table which will store the passed result, so THIS IS THE OUTPUT.
579 -- return : true if pattern found and parsed, nil otherwise.
580 function lib:ParseMessage(message, event)
581  
582 -- -- local currTime -- timer
583  
584  
585 -- currTime = GetTime() -- timer
586 if not self.eventTable[event] then self.eventTable[event] = self:LoadPatternList(event) end
587 local list = self.eventTable[event]
588 -- self.timer.ParseMessage_LoadPatternList = self.timer.ParseMessage_LoadPatternList + GetTime() - currTime -- timer
589  
590 if not list then return end
591  
592 -- Get the table to store parsed results.
593 if not self.info then
594 -- timer = GetTime() -- timer
595 self.info = self:GetCompost():Acquire()
596 -- self.timer.Compost_Acquire = GetTime() - timer + self.timer.Compost_Acquire -- timer
597 else
598 -- timer = GetTime() -- timer
599 self.info = self:GetCompost():Recycle(self.info)
600 -- self.timer.Compost_Recycle = GetTime() - timer + self.timer.Compost_Recycle -- timer
601 end
602  
603  
604 -- currTime = GetTime() -- timer
605 local pattern = self:FindPattern(message, list)
606 -- self.timer.ParseMessage_FindPattern = GetTime() - currTime + self.timer.ParseMessage_FindPattern -- timer
607  
608  
609 if not pattern then
610 -- create "unknown" event type.
611 self.info.type = "unknown"
612 self.info.message = message
613 return true
614 end
615  
616 -- currTime = GetTime() -- timer
617 self:ParseInformation(pattern)
618 -- self.timer.ParseMessage_ParseInformation = GetTime() - currTime + self.timer.ParseMessage_ParseInformation -- timer
619  
620  
621 -- currTime = GetTime() -- timer
622 if self.info.type == "hit" or self.info.type == "environment" then
623 self:ParseTrailers(message)
624 end
625 -- self.timer.ParseMessage_ParseTrailers = GetTime() - currTime + self.timer.ParseMessage_ParseTrailers -- timer
626  
627 -- currTime = GetTime() -- timer
628 self:ConvertTypes(self.info)
629 -- self.timer.ParseMessage_ConvertTypes = GetTime() - currTime + self.timer.ParseMessage_ConvertTypes -- timer
630  
631 return true
632  
633  
634 end
635  
636  
637 -- Search for pattern in 'patternList' which matches 'message', parsed tokens will be stored in table self.info
638 function lib:FindPattern(message, patternList)
639  
640 local pt, timer, found
641  
642 for i, v in patternList do
643  
644 -- timer = GetTime() -- timer
645 if not self.patternTable[v] then self.patternTable[v] = self:LoadPatternInfo(v) end
646 -- self.timer.ParseMessage_FindPattern_LoadPatternInfo = GetTime() - timer + self.timer.ParseMessage_FindPattern_LoadPatternInfo -- timer
647  
648 pt = self.patternTable[v]
649  
650 found = false
651  
652 -- timer = GetTime() -- timer
653 if self:OptimizerCheck(message, v) then
654 -- timer = GetTime() -- timer
655 found, self.info = FindString[pt.tc](message, pt.pattern, self.info)
656 -- self.timer.ParseMessage_FindPattern_Regexp_FindString = GetTime() - timer + self.timer.ParseMessage_FindPattern_Regexp_FindString -- timer
657 end
658 -- self.timer.ParseMessage_FindPattern_Regexp = GetTime() - timer + self.timer.ParseMessage_FindPattern_Regexp -- timer
659  
660 if found then
661 -- self:Print(message.." = " .. v .. ":" .. pt.pattern) -- debug
662 return v
663 end
664  
665  
666 end
667  
668  
669 end
670  
671  
672 -- Parses for trailors.
673 function lib:ParseTrailers(message)
674 local found, amount, info
675  
676 info = self.info
677  
678  
679 if not self.trailers then
680 self.trailers = {
681 CRUSHING_TRAILER = self:ConvertPattern(CRUSHING_TRAILER),
682 GLANCING_TRAILER = self:ConvertPattern(GLANCING_TRAILER),
683 ABSORB_TRAILER = self:ConvertPattern(ABSORB_TRAILER),
684 BLOCK_TRAILER = self:ConvertPattern(BLOCK_TRAILER),
685 RESIST_TRAILER = self:ConvertPattern(RESIST_TRAILER),
686 VULNERABLE_TRAILER = self:ConvertPattern(VULNERABLE_TRAILER),
687 }
688 end
689  
690 found = string.find(message, self.trailers.CRUSHING_TRAILER)
691 if found then
692 info.isCrushing = true
693 end
694 found = string.find(message, self.trailers.GLANCING_TRAILER)
695 if found then
696 info.isGlancing = true
697 end
698 found, _, amount = string.find(message, self.trailers.ABSORB_TRAILER)
699 if found then
700 info.amountAbsorb = amount
701 end
702 found, _, amount = string.find(message, self.trailers.BLOCK_TRAILER)
703 if found then
704 info.amountBlock = amount
705 end
706 found, _, amount = string.find(message, self.trailers.RESIST_TRAILER)
707 if found then
708 info.amountResist = amount
709 end
710 found, _, amount = string.find(message, self.trailers.VULNERABLE_TRAILER)
711 if found then
712 info.amountVulnerable = amount
713 end
714  
715 end
716  
717 function lib:ParseInformation(patternName)
718  
719 local patternInfo = self.patternTable[patternName]
720 local info = self.info
721  
722 -- Create an info table from pattern table, copies everything except the pattern string.
723 for i, v in patternInfo do
724 if i == 1 then
725 info.type = v
726 elseif type(i) == "number" then
727 if type(v) == "number" and v < 100 then
728 info[ self:GetInfoFieldName( self.patternTable[patternName][1], i) ] = info[v]
729 else
730 info[ self:GetInfoFieldName( self.patternTable[patternName][1], i) ] = v
731 end
732 end
733 end
734  
735 if info.type == "honor" and not info.amount then
736 info.isDishonor = true
737  
738 elseif info.type == "durability" and not info.item then
739 info.isAllItems = true
740 end
741  
742 for i in ipairs(info) do
743 info[i] = nil
744 end
745  
746 end
747  
748 function lib:ConvertTypes(info)
749 for i in info do
750 if string.find(i, "^amount") then info[i] = tonumber(info[i]) end
751 end
752 end
753  
754 function lib:OptimizerCheck(message, patternName)
755  
756 --if 1 then return true end
757 if not ParserLibOptimizer then return true end
758  
759 if not ParserLibOptimizer[patternName] then return true end
760  
761 if string.find(message, ParserLibOptimizer[patternName], 1, true) then return true end
762  
763 return false
764 end
765  
766 -- Most of the parts were learnt from BabbleLib by chknight, so credits goes to him.
767 function lib:Curry(pattern)
768 local cp, tt, n, f, o
769 local DoNothing = function(tok) return tok end
770  
771 tt = {}
772 for tk in string.gfind(pattern, "%%%d?%$?([sd])") do
773 table.insert(tt, tk)
774 end
775  
776 cp = { self:ConvertPattern(pattern, true) }
777 cp.p = cp[1]
778  
779 n = table.getn(cp)
780 for i=1,n-1 do
781 cp[i] = cp[i+1]
782 end
783 table.remove(cp, n)
784  
785 f = {}
786 o = {}
787 n = table.getn(tt)
788 for i=1, n do
789 if tt[i] == "s" then
790 f[i] = DoNothing
791 else
792 f[i] = tonumber
793 end
794 end
795  
796 if not cp[1] then
797 if n == 0 then
798 return function() end
799 elseif n == 1 then
800 return function(text)
801 _, _, o[1] = string.find(text, cp.p)
802 if o[1] then
803 return f[1](o[1])
804 end
805 end
806 elseif n == 2 then
807 return function(text)
808 _, _, o[1], o[2]= string.find(text, cp.p)
809 if o[1] then
810 return f[1](o[1]), f[2](o[2])
811 end
812 end
813 elseif n == 3 then
814 return function(text)
815 _, _, o[1], o[2], o[3] = string.find(text, cp.p)
816 if o[1] then
817 return f[1](o[1]), f[2](o[2]), f[3](o[3])
818 end
819 end
820 elseif n == 4 then
821 return function(text)
822 _, _, o[1], o[2], o[3], o[4] = string.find(text, cp.p)
823 if o[1] then
824 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4])
825 end
826 end
827 elseif n == 5 then
828 return function(text)
829 _, _, o[1], o[2], o[3], o[4], o[5] = string.find(text, cp.p)
830 if o[1] then
831 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5])
832 end
833 end
834 elseif n == 6 then
835 return function(text)
836 _, _, o[1], o[2], o[3], o[4], o[5], o[6] = string.find(text, cp.p)
837 if o[1] then
838 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6])
839 end
840 end
841 elseif n == 7 then
842 return function(text)
843 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7] = string.find(text, cp.p)
844 if o[1] then
845 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6]), f[7](o[7])
846 end
847 end
848 elseif n == 8 then
849 return function(text)
850 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8] = string.find(text, cp.p)
851 if o[1] then
852 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6]), f[7](o[7]), f[8](o[8])
853 end
854 end
855 elseif n == 9 then
856 return function(text)
857 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9] = string.find(text, cp.p)
858 if o[1] then
859 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6]), f[7](o[7]), f[8](o[8]), f[9](o[9])
860 end
861 end
862 end
863 else
864 if n == 0 then
865 return function() end
866 elseif n == 1 then
867 return function(text)
868 _, _, o[1] = string.find(text, cp.p)
869 if o[1] then
870 return f[cp[1]](o[cp[1]])
871 end
872 end elseif n == 2 then
873 return function(text)
874 _, _, o[1], o[2] = string.find(text, cp.p)
875 if o[1] then
876 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]])
877 end
878 end elseif n == 3 then
879 return function(text)
880 _, _, o[1], o[2], o[3] = string.find(text, cp.p)
881 if o[1] then
882 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]])
883 end
884 end
885 elseif n == 4 then
886 return function(text)
887 _, _, o[1], o[2], o[3], o[4] = string.find(text, cp.p)
888 if o[1] then
889 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]])
890 end
891 end elseif n == 5 then
892 return function(text)
893 _, _, o[1], o[2], o[3], o[4], o[5] = string.find(text, cp.p)
894 if o[1] then
895 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]])
896 end
897 end elseif n == 6 then
898 return function(text)
899 _, _, o[1], o[2], o[3], o[4], o[5], o[6] = string.find(text, cp.p)
900 if o[1] then
901 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]])
902 end
903 end elseif n == 7 then
904 return function(text)
905 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7] = string.find(text, cp.p)
906 if o[1] then
907 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]]), f[cp[7]](o[cp[7]])
908 end
909 end elseif n == 8 then
910 return function(text)
911 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8] = string.find(text, cp.p)
912 if o[1] then
913 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]]), f[cp[7]](o[cp[7]]), f[cp[8]](o[cp[8]])
914 end
915 end elseif n == 9 then
916 return function(text)
917 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9] = string.find(text, cp.p)
918 if o[1] then
919 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]]), f[cp[7]](o[cp[7]]), f[cp[8]](o[cp[8]]), f[cp[9]](o[cp[9]])
920 end
921 end
922 end
923 end
924 end
925  
926  
927 function lib:PrintTable(args)
928 for k, v in args do
929 ChatFrame1:AddMessage(tostring(k) .. " = " .. tostring(v));
930 end
931 ChatFrame1:AddMessage("");
932 end
933  
934 -- Used to test the correcteness of ParserLib on different languages.
935 function lib:TestPatterns(sendToClients)
936  
937  
938 self:LoadEverything()
939  
940  
941 -- Creating the combat messages.
942 local testNumber = 123
943 local message
944 local messages = self:GetCompost():Acquire()
945 for patternName in self.patternTable do
946 messages[patternName] = self:GetCompost():Acquire()
947 messages[patternName].message = getglobal(patternName)
948 for i, v in self.patternTable[patternName] do
949 if i ~= "tc" and type(v) == "number" and v < 100 and i~=1 then
950 messages[patternName][v] = self:GetInfoFieldName(self.patternTable[patternName][1], i)
951 end
952 end
953 for i, v in ipairs(messages[patternName]) do
954 if string.find(v, "^amount") then
955 messages[patternName].message = string.gsub(messages[patternName].message, "%%%d?%$?d", testNumber, 1)
956 else
957 messages[patternName].message = string.gsub(messages[patternName].message, "%%%d?%$?s", string.upper(v), 1)
958 end
959 end
960 end
961  
962  
963 -- Begin the test.
964  
965 local info, msg
966 local startTime = GetTime()
967 local startMem = gcinfo()
968  
969 for _, event in self.supportedEvents do
970 for _, pattern in self:LoadPatternList(event) do
971 msg = messages[pattern].message
972 if sendToClients then self:OnEvent(event, msg) end
973 if self:ParseMessage(msg, event) then
974 info = self.info
975 for i, v in ipairs(messages[pattern]) do
976 if not info[v]
977 or ( string.find(v, "^amount") and info[v] ~= testNumber )
978 or ( not string.find(v, "^amount") and info[v] ~= string.upper(v) ) then
979 self:Print("Event: " .. event)
980 self:Print("Pattern: " .. pattern)
981 self:Print("Message: " .. msg)
982 self:PrintTable(messages[pattern])
983 self:PrintTable(info)
984 end
985 end
986 end
987 end
988 end
989  
990 self:Print( string.format("Test completed in %.4fs, memory cost %.2fKB.", GetTime() - startTime, gcinfo() - startMem) )
991  
992 self:GetCompost():Reclaim(messages, 1)
993  
994 end
995  
996 function lib:LoadEverything()
997  
998 -- Load all patterns and events.
999 for _, v in self.supportedEvents do
1000 for _, w in self:LoadPatternList(v) do
1001 if not self.patternTable[w] then
1002 self.patternTable[w] = self:LoadPatternInfo(w)
1003 end
1004 end
1005 end
1006  
1007 end
1008  
1009 function lib:PrintTimers()
1010 if not self.timer then return end
1011  
1012 local total = 0
1013 for i in self.timer do
1014 total = total + self.timer[i]
1015 end
1016  
1017 if not self.timerIndex then
1018 self.timerIndex = {}
1019 for i in self.timer do
1020 table.insert(self.timerIndex, i)
1021 end
1022 table.sort(self.timerIndex)
1023 end
1024  
1025 DEFAULT_CHAT_FRAME:AddMessage("Time\t%\tDescription")
1026 for i, idx in self.timerIndex do
1027 DEFAULT_CHAT_FRAME:AddMessage(string.format("%.3f\t%.1f\t%s", self.timer[idx], 100*self.timer[idx]/total, idx) )
1028 end
1029  
1030 DEFAULT_CHAT_FRAME:AddMessage(total .. "\t100\tTotal")
1031 end
1032 -- Used to load eventTable elements on demand.
1033 function lib:LoadPatternList(eventName)
1034 local list
1035  
1036 --------------- Melee Hits ----------------
1037  
1038 if eventName == "CHAT_MSG_COMBAT_SELF_HITS" then
1039  
1040 if not self.eventTable["CHAT_MSG_COMBAT_SELF_HITS"] then
1041  
1042 self.eventTable["CHAT_MSG_COMBAT_SELF_HITS"] =
1043 self:LoadPatternCategoryTree(
1044 {
1045 "HitSelf",
1046 "EnvSelf",
1047 }
1048 )
1049  
1050 end
1051  
1052 list = self.eventTable["CHAT_MSG_COMBAT_SELF_HITS"]
1053  
1054 elseif eventName == "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS"
1055 or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS"
1056 or eventName == "CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"
1057 or eventName == "CHAT_MSG_COMBAT_PARTY_HITS"
1058 or eventName == "CHAT_MSG_COMBAT_PET_HITS" then
1059  
1060 if not self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"] then
1061 self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"] =
1062 self:LoadPatternCategoryTree( {
1063 "HitOtherOther",
1064 "EnvOther",
1065 } )
1066 end
1067 list = self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"]
1068  
1069  
1070 elseif eventName == "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"
1071 or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS" then
1072  
1073 if not self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"] then
1074 self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"] =
1075 self:LoadPatternCategoryTree( {
1076 {
1077 "HitOtherOther",
1078 "HitOtherSelf",
1079 },
1080 "EnvOther",
1081 } )
1082 end
1083 list = self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"]
1084  
1085  
1086  
1087 --------------- Melee Misses ----------------
1088  
1089  
1090  
1091 elseif eventName == "CHAT_MSG_COMBAT_SELF_MISSES" then
1092 if not self.eventTable["CHAT_MSG_COMBAT_SELF_MISSES"] then
1093 self.eventTable["CHAT_MSG_COMBAT_SELF_MISSES"] =
1094 self:LoadPatternCategoryTree( {
1095 "MissSelf",
1096 } )
1097 end
1098 list = self.eventTable["CHAT_MSG_COMBAT_SELF_MISSES"]
1099  
1100 elseif eventName == "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES"
1101 or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES"
1102 or eventName == "CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"
1103 or eventName == "CHAT_MSG_COMBAT_PARTY_MISSES"
1104 or eventName == "CHAT_MSG_COMBAT_PET_MISSES" then
1105  
1106 if not self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"] then
1107 self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"] =
1108 self:LoadPatternCategoryTree( {
1109 "MissOtherOther",
1110 } )
1111 end
1112  
1113 list = self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"]
1114  
1115  
1116 elseif eventName == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES"
1117 or eventName == "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES" then
1118  
1119 if not self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"] then
1120 self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"] =
1121 self:LoadPatternCategoryTree( {
1122 {
1123 "MissOtherOther",
1124 "MissOtherSelf",
1125 }
1126 } )
1127 end
1128  
1129 list = self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"]
1130  
1131 --------------- Spell Buffs ----------------
1132 elseif eventName == "CHAT_MSG_SPELL_SELF_BUFF" then
1133 if not self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"] then
1134  
1135 if GetLocale() ~= "deDE" then
1136 self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"] = self:LoadPatternCategoryTree(
1137 {
1138 "HealSelf",
1139 "EnchantSelf",
1140 "CastSelf",
1141 "PerformSelf",
1142 "DispelFailSelf",
1143 "SPELLCASTSELFSTART",
1144 "SPELLPERFORMSELFSTART",
1145 {
1146 "DrainSelf",
1147 "PowerGainSelf",
1148 "ExtraAttackSelf",
1149 },
1150 "SPELLSPLITDAMAGESELFOTHER",
1151 {
1152 "ProcResistSelf",
1153 "SpellMissSelf",
1154 }
1155 }
1156 )
1157  
1158 else
1159 self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"] = self:LoadPatternCategoryTree(
1160 {
1161 "HealSelf",
1162 "CastSelf",
1163 "PerformSelf",
1164 "DispelFailSelf",
1165 "SPELLCASTSELFSTART",
1166 "SPELLPERFORMSELFSTART",
1167 {
1168 "DrainSelf",
1169 "PowerGainSelf",
1170 "ExtraAttackSelf",
1171 },
1172 "SPELLSPLITDAMAGESELFOTHER",
1173 {
1174 "ProcResistSelf",
1175 "SpellMissSelf",
1176 }
1177 }
1178 )
1179 end
1180  
1181 end
1182  
1183 list = self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"]
1184  
1185  
1186 elseif eventName == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF"
1187 or eventName == "CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF"
1188 or eventName == "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF"
1189 or eventName == "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF"
1190 or eventName == "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"
1191 or eventName == "CHAT_MSG_SPELL_PARTY_BUFF"
1192 or eventName == "CHAT_MSG_SPELL_PET_BUFF" then
1193  
1194 if not self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] then
1195  
1196 if GetLocale() ~= "deDE" then
1197 self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] = self:LoadPatternCategoryTree(
1198 {
1199 {
1200 "HealOther",
1201 "PowerGainOther",
1202 "ExtraAttackOther",
1203 "DrainOther",
1204 },
1205 "SPELLCASTOTHERSTART",
1206 {
1207 "EnchantOther",
1208 "CastOther",
1209 "PerformOther",
1210 },
1211 "SPELLPERFORMOTHERSTART",
1212 "SpellMissOther",
1213 "ProcResistOther",
1214 "SplitDamageOther",
1215 "DispelFailOther",
1216 }
1217 )
1218  
1219 else -- Remove "EnchantOther" from German, since it's 100% ambiguous with SIMPLECASTOTHEROTHER, which is unsolvable.
1220 self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] = self:LoadPatternCategoryTree(
1221 {
1222 {
1223 "HealOther",
1224 "PowerGainOther",
1225 "ExtraAttackOther",
1226 "DrainOther",
1227 },
1228 "SPELLCASTOTHERSTART",
1229 {
1230 "CastOther",
1231 "PerformOther",
1232 },
1233 "SPELLPERFORMOTHERSTART",
1234 "SpellMissOther",
1235 "ProcResistOther",
1236 "SplitDamageOther",
1237 "DispelFailOther",
1238 }
1239 )
1240 end
1241 end
1242  
1243 list = self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"]
1244  
1245  
1246 --------------- Spell Damages ----------------
1247  
1248 elseif eventName == "CHAT_MSG_SPELL_SELF_DAMAGE" then
1249 if not self.eventTable["CHAT_MSG_SPELL_SELF_DAMAGE"] then
1250 self.eventTable["CHAT_MSG_SPELL_SELF_DAMAGE"] =
1251 self:LoadPatternCategoryTree( {
1252 "SpellHitSelf",
1253 {
1254 "CastSelf",
1255 "DurabilityDamageSelf",
1256 },
1257 "PerformSelf",
1258 "SpellMissSelf",
1259 "SPELLCASTSELFSTART",
1260 "SPELLPERFORMSELFSTART",
1261 "InterruptSelf",
1262 "DispelFailSelf",
1263 "ExtraAttackSelf",
1264 "DrainSelf",
1265  
1266 } )
1267  
1268 end
1269 list = self.eventTable["CHAT_MSG_SPELL_SELF_DAMAGE"]
1270  
1271  
1272 elseif eventName == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE"
1273 or eventName == "CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE"
1274 or eventName == "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE"
1275 or eventName == "CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE"
1276 or eventName == "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"
1277 or eventName == "CHAT_MSG_SPELL_PARTY_DAMAGE"
1278 or eventName == "CHAT_MSG_SPELL_PET_DAMAGE" then
1279  
1280 if not self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"] then
1281 self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"] =
1282 self:LoadPatternCategoryTree( {
1283 "SpellHitOther",
1284 "SPELLCASTOTHERSTART",
1285 "SPELLPERFORMOTHERSTART",
1286 "DrainOther",
1287 "SpellMissOther",
1288 {
1289 "INSTAKILLOTHER",
1290 "INSTAKILLSELF",
1291 },
1292 {
1293 "PROCRESISTOTHEROTHER",
1294 "PROCRESISTOTHERSELF",
1295 },
1296 "SplitDamageOther",
1297 {
1298 "CastOther",
1299 "InterruptOther",
1300 "DurabilityDamageOther",
1301 },
1302 "PerformOther",
1303 "ExtraAttackOther",
1304 {
1305 "DISPELFAILEDOTHEROTHER",
1306 "DISPELFAILEDOTHERSELF",
1307 },
1308 })
1309  
1310 end
1311 list = self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"]
1312  
1313  
1314 --------------- Periodic Buffs ----------------
1315  
1316 elseif eventName == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" then
1317  
1318 if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"] then
1319  
1320 self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"] =
1321 self:LoadPatternCategoryTree( {
1322 {
1323 "HotOther",
1324 "HotSelf",
1325 },
1326 {
1327 "BuffSelf",
1328 "BuffOther",
1329 "PowerGainOther",
1330 "PowerGainSelf",
1331 },
1332 "DrainSelf",
1333 "DotSelf", -- Don't think this will hapen but add it anyway.
1334 } )
1335 end
1336 list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"]
1337  
1338  
1339 elseif eventName == "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS"
1340 or eventName == "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS"
1341 or eventName == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"
1342 or eventName == "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS" then
1343  
1344 if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"] then
1345 self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"] =
1346 self:LoadPatternCategoryTree( {
1347 {
1348 "HotOther",
1349 -- "DrainOther", -- Dont think this would happen but add it anyway.
1350 },
1351 {
1352 "BuffOther",
1353 "PowerGainOther",
1354 "DrainOther", -- When other players use Skull of Impending Doom.
1355 },
1356 "DotOther", -- Dont think this will happen but add anyway.
1357 "DebuffOther", -- Was fired on older WoW version.
1358 } )
1359 end
1360  
1361 list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"]
1362  
1363  
1364  
1365 --------------- Periodic Damages ----------------
1366  
1367 elseif eventName == "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE" then
1368 if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"] then
1369  
1370 self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"] =
1371 self:LoadPatternCategoryTree( {
1372 {
1373 "DotSelf",
1374 "DotOther",
1375 },
1376 {
1377 "DebuffSelf",
1378 "DebuffOther",
1379 },
1380 {
1381 "SPELLLOGABSORBOTHEROTHER",
1382 "SPELLLOGABSORBOTHERSELF",
1383 "SPELLLOGABSORBSELFSELF",
1384 "SPELLLOGABSORBSELFOTHER",
1385 },
1386 "DrainSelf",
1387 } )
1388 end
1389 list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"]
1390  
1391  
1392  
1393 elseif eventName == "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"
1394 or eventName == "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE"
1395 or eventName == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"
1396 or eventName == "CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE" then
1397  
1398 if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] then
1399 self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] =
1400 self:LoadPatternCategoryTree( {
1401 "DebuffOther",
1402 "DotOther",
1403 {
1404 "SPELLLOGABSORBOTHEROTHER",
1405 "SPELLLOGABSORBSELFOTHER",
1406 },
1407 "DrainOther",
1408 {
1409 "PowerGainOther",
1410 "BuffOther", -- Was fired on older WoW version.
1411 }
1412 } )
1413 end
1414 list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"]
1415  
1416 --------------- Damage Shields ----------------
1417  
1418  
1419 elseif eventName == "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF" then
1420 if not self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] then
1421 self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] = {
1422 "SPELLRESISTOTHEROTHER",
1423 "SPELLRESISTSELFOTHER",
1424 "DAMAGESHIELDOTHEROTHER",
1425 "DAMAGESHIELDSELFOTHER",
1426 }
1427 table.sort(self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] , PatternCompare)
1428 end
1429 list = self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"]
1430  
1431 elseif eventName == "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS" then
1432 if not self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] then
1433 self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] = {
1434 "SPELLRESISTOTHEROTHER",
1435 "SPELLRESISTOTHERSELF",
1436 "DAMAGESHIELDOTHEROTHER",
1437 "DAMAGESHIELDOTHERSELF",
1438 }
1439 table.sort(self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] , PatternCompare)
1440 end
1441 list = self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"]
1442  
1443  
1444  
1445 --------------- Auras ----------------
1446  
1447 elseif eventName == "CHAT_MSG_SPELL_AURA_GONE_PARTY"
1448 or eventName == "CHAT_MSG_SPELL_AURA_GONE_OTHER" then
1449  
1450 if not self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"] then
1451 self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"] = {
1452 "AURAREMOVEDOTHER",
1453 }
1454 table.sort(self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"] , PatternCompare)
1455 end
1456 list = self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"]
1457  
1458 elseif eventName == "CHAT_MSG_SPELL_AURA_GONE_SELF" then
1459  
1460 if not self.eventTable["CHAT_MSG_SPELL_AURA_GONE_SELF"] then
1461 self.eventTable["CHAT_MSG_SPELL_AURA_GONE_SELF"] = {
1462 "AURAREMOVEDOTHER",
1463 "AURAREMOVEDSELF",
1464 }
1465 table.sort(self.eventTable["CHAT_MSG_SPELL_AURA_GONE_SELF"] , PatternCompare)
1466 end
1467 list = self.eventTable["CHAT_MSG_SPELL_AURA_GONE_SELF"]
1468  
1469 elseif eventName == "CHAT_MSG_SPELL_BREAK_AURA" then
1470  
1471 if not self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"] then
1472 self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"] = {
1473 "AURADISPELSELF",
1474 "AURADISPELOTHER",
1475 }
1476 table.sort(self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"] , PatternCompare)
1477 end
1478 list = self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"]
1479  
1480  
1481  
1482 elseif eventName == "CHAT_MSG_SPELL_ITEM_ENCHANTMENTS" then
1483  
1484 if not self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] then
1485 self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] = {
1486 "ITEMENCHANTMENTADDSELFSELF",
1487 "ITEMENCHANTMENTADDSELFOTHER",
1488 "ITEMENCHANTMENTADDOTHEROTHER",
1489 "ITEMENCHANTMENTADDOTHERSELF",
1490 }
1491 table.sort(self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] , PatternCompare)
1492 end
1493 list = self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"]
1494  
1495 --------------- Trade Skills ----------------
1496  
1497  
1498 elseif eventName == "CHAT_MSG_SPELL_TRADESKILLS" then
1499 if not self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"] then
1500 self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"] = {
1501 "TRADESKILL_LOG_FIRSTPERSON",
1502 "TRADESKILL_LOG_THIRDPERSON",
1503 "FEEDPET_LOG_FIRSTPERSON",
1504 "FEEDPET_LOG_THIRDPERSON",
1505 }
1506 table.sort(self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"], PatternCompare )
1507 end
1508 list = self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"]
1509  
1510 elseif eventName == "CHAT_MSG_SPELL_FAILED_LOCALPLAYER" then
1511  
1512 if not self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"] then
1513 self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"] = {
1514 "SPELLFAILPERFORMSELF",
1515 "SPELLFAILCASTSELF",
1516 }
1517 table.sort(self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"], PatternCompare)
1518 end
1519 list = self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"]
1520  
1521  
1522 elseif eventName == "CHAT_MSG_COMBAT_FACTION_CHANGE" then
1523  
1524 if not self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] then
1525  
1526 self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] = {
1527 "FACTION_STANDING_CHANGED",
1528 "FACTION_STANDING_DECREASED",
1529 "FACTION_STANDING_INCREASED",
1530 }
1531 table.sort(self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] , PatternCompare)
1532 end
1533 list = self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"]
1534  
1535 elseif eventName == "CHAT_MSG_COMBAT_HONOR_GAIN" then
1536  
1537 if not self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"] then
1538 self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"] = {
1539 "COMBATLOG_HONORAWARD",
1540 "COMBATLOG_HONORGAIN",
1541 "COMBATLOG_DISHONORGAIN",
1542 }
1543 table.sort(self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"] , PatternCompare)
1544 end
1545 list = self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"]
1546 elseif eventName == "CHAT_MSG_COMBAT_XP_GAIN" then
1547  
1548 if not self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"] then
1549 self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"] = {
1550 "COMBATLOG_XPGAIN",
1551 "COMBATLOG_XPGAIN_EXHAUSTION1",
1552 "COMBATLOG_XPGAIN_EXHAUSTION1_GROUP",
1553 "COMBATLOG_XPGAIN_EXHAUSTION1_RAID",
1554 "COMBATLOG_XPGAIN_EXHAUSTION2",
1555 "COMBATLOG_XPGAIN_EXHAUSTION2_GROUP",
1556 "COMBATLOG_XPGAIN_EXHAUSTION2_RAID",
1557 "COMBATLOG_XPGAIN_EXHAUSTION4",
1558 "COMBATLOG_XPGAIN_EXHAUSTION4_GROUP",
1559 "COMBATLOG_XPGAIN_EXHAUSTION4_RAID",
1560 "COMBATLOG_XPGAIN_EXHAUSTION5",
1561 "COMBATLOG_XPGAIN_EXHAUSTION5_GROUP",
1562 "COMBATLOG_XPGAIN_EXHAUSTION5_RAID",
1563 "COMBATLOG_XPGAIN_FIRSTPERSON",
1564 "COMBATLOG_XPGAIN_FIRSTPERSON_GROUP",
1565 "COMBATLOG_XPGAIN_FIRSTPERSON_RAID",
1566 "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED",
1567 "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_GROUP",
1568 "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_RAID",
1569 "COMBATLOG_XPLOSS_FIRSTPERSON_UNNAMED",
1570 }
1571 table.sort(self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"] , PatternCompare)
1572 end
1573 list = self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"]
1574  
1575 elseif eventName == "CHAT_MSG_COMBAT_FRIENDLY_DEATH"
1576 or eventName == "CHAT_MSG_COMBAT_HOSTILE_DEATH" then
1577  
1578 if not self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] then
1579 self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] = {
1580 "SELFKILLOTHER",
1581 "PARTYKILLOTHER",
1582 "UNITDESTROYEDOTHER",
1583 "UNITDIESOTHER",
1584 "UNITDIESSELF",
1585 }
1586  
1587 table.sort(self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] , PatternCompare)
1588 end
1589 list = self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"]
1590  
1591 end
1592  
1593  
1594 if not list then
1595 -- self:Print(string.format("Event '%s' not found.", eventName), 1, 0,0); -- debug
1596 end
1597  
1598 return list
1599  
1600 end
1601  
1602 function lib:LoadPatternCategory(category)
1603  
1604 local list
1605  
1606 if category == "AuraChange" then list = {
1607 "AURACHANGEDOTHER",
1608 "AURACHANGEDSELF",
1609 }
1610 elseif category == "AuraDispel" then list = {
1611 "AURADISPELOTHER",
1612 "AURADISPELSELF",
1613 }
1614 elseif category == "BuffOther" then list = {
1615 "AURAADDEDOTHERHELPFUL",
1616 "AURAAPPLICATIONADDEDOTHERHELPFUL",
1617 }
1618 elseif category == "BuffSelf" then list = {
1619 "AURAADDEDSELFHELPFUL",
1620 "AURAAPPLICATIONADDEDSELFHELPFUL",
1621 }
1622 elseif category == "CastOther" then list = {
1623 "SIMPLECASTOTHEROTHER",
1624 "SIMPLECASTOTHERSELF",
1625 "SPELLTERSE_OTHER",
1626 }
1627 elseif category == "CastSelf" then list = {
1628 "SIMPLECASTSELFOTHER",
1629 "SIMPLECASTSELFSELF",
1630 "SPELLTERSE_SELF",
1631 }
1632 elseif category == "DebuffOther" then list = {
1633 "AURAADDEDOTHERHARMFUL",
1634 "AURAAPPLICATIONADDEDOTHERHARMFUL",
1635 }
1636 elseif category == "DebuffSelf" then list = {
1637 "AURAADDEDSELFHARMFUL",
1638 "AURAAPPLICATIONADDEDSELFHARMFUL",
1639 }
1640 elseif category == "DispelFailOther" then list = {
1641 "DISPELFAILEDOTHEROTHER",
1642 "DISPELFAILEDOTHERSELF",
1643  
1644 }
1645 elseif category == "DispelFailSelf" then list = {
1646 "DISPELFAILEDSELFOTHER",
1647 "DISPELFAILEDSELFSELF",
1648 }
1649 elseif category == "DmgShieldOther" then list = {
1650 "DAMAGESHIELDOTHEROTHER",
1651 "DAMAGESHIELDOTHERSELF",
1652 }
1653 elseif category == "DmgShieldSelf" then list = {
1654 "DAMAGESHIELDSELFOTHER",
1655 }
1656 elseif category == "DurabilityDamageSelf" then list = {
1657 "SPELLDURABILITYDAMAGEALLSELFOTHER",
1658 "SPELLDURABILITYDAMAGESELFOTHER",
1659 }
1660 elseif category == "DurabilityDamageOther" then list = {
1661 "SPELLDURABILITYDAMAGEALLOTHEROTHER",
1662 "SPELLDURABILITYDAMAGEALLOTHERSELF",
1663 "SPELLDURABILITYDAMAGEOTHEROTHER",
1664 "SPELLDURABILITYDAMAGEOTHERSELF",
1665 }
1666 elseif category == "EnchantOther" then list = {
1667 "ITEMENCHANTMENTADDOTHEROTHER",
1668 "ITEMENCHANTMENTADDOTHERSELF",
1669 }
1670 elseif category == "EnchantSelf" then list = {
1671 "ITEMENCHANTMENTADDSELFOTHER",
1672 "ITEMENCHANTMENTADDSELFSELF",
1673 }
1674 elseif category == "ExtraAttackOther" then list = {
1675 "SPELLEXTRAATTACKSOTHER",
1676 "SPELLEXTRAATTACKSOTHER_SINGULAR",
1677 }
1678 elseif category == "ExtraAttackSelf" then list = {
1679 "SPELLEXTRAATTACKSSELF",
1680 "SPELLEXTRAATTACKSSELF_SINGULAR",
1681 }
1682 elseif category == "Fade" then list = {
1683 "AURAREMOVEDOTHER",
1684 "AURAREMOVEDSELF",
1685 }
1686 elseif category == "HealOther" then list = {
1687 "HEALEDCRITOTHEROTHER",
1688 "HEALEDCRITOTHERSELF",
1689 "HEALEDOTHEROTHER",
1690 "HEALEDOTHERSELF",
1691 }
1692 elseif category == "HealSelf" then list = {
1693 "HEALEDCRITSELFOTHER",
1694 "HEALEDCRITSELFSELF",
1695 "HEALEDSELFOTHER",
1696 "HEALEDSELFSELF",
1697 }
1698 elseif category == "HitOtherOther" then list = {
1699 "COMBATHITCRITOTHEROTHER",
1700 "COMBATHITCRITSCHOOLOTHEROTHER",
1701 "COMBATHITOTHEROTHER",
1702 "COMBATHITSCHOOLOTHEROTHER",
1703 }
1704 elseif category == "HitOtherSelf" then list = {
1705  
1706 "COMBATHITCRITOTHERSELF",
1707 "COMBATHITCRITSCHOOLOTHERSELF",
1708 "COMBATHITOTHERSELF",
1709 "COMBATHITSCHOOLOTHERSELF",
1710 }
1711 elseif category == "HitSelf" then list = {
1712 "COMBATHITSCHOOLSELFOTHER",
1713 "COMBATHITSELFOTHER",
1714 "COMBATHITCRITSCHOOLSELFOTHER",
1715 "COMBATHITCRITSELFOTHER",
1716 }
1717 elseif category == "MissOtherOther" then list = {
1718 "MISSEDOTHEROTHER",
1719 "VSABSORBOTHEROTHER",
1720 "VSBLOCKOTHEROTHER",
1721 "VSDEFLECTOTHEROTHER",
1722 "VSDODGEOTHEROTHER",
1723 "VSEVADEOTHEROTHER",
1724 "VSIMMUNEOTHEROTHER",
1725 "VSPARRYOTHEROTHER",
1726 "VSRESISTOTHEROTHER",
1727 "IMMUNEDAMAGECLASSOTHEROTHER",
1728 "IMMUNEOTHEROTHER",
1729  
1730 }
1731 elseif category == "MissOtherSelf" then list = {
1732 "MISSEDOTHERSELF",
1733 "VSABSORBOTHERSELF",
1734 "VSBLOCKOTHERSELF",
1735 "VSDEFLECTOTHERSELF",
1736 "VSDODGEOTHERSELF",
1737 "VSEVADEOTHERSELF",
1738 "VSIMMUNEOTHERSELF",
1739 "VSPARRYOTHERSELF",
1740 "VSRESISTOTHERSELF",
1741 "IMMUNEDAMAGECLASSOTHERSELF",
1742 "IMMUNEOTHERSELF",
1743 }
1744 elseif category == "MissSelf" then list = {
1745 "MISSEDSELFOTHER",
1746 "VSABSORBSELFOTHER",
1747 "VSBLOCKSELFOTHER",
1748 "VSDEFLECTSELFOTHER",
1749 "VSDODGESELFOTHER",
1750 "VSEVADESELFOTHER",
1751 "VSIMMUNESELFOTHER",
1752 "VSPARRYSELFOTHER",
1753 "VSRESISTSELFOTHER",
1754 "IMMUNEDAMAGECLASSSELFOTHER",
1755 "IMMUNESELFOTHER",
1756 "IMMUNESELFSELF",
1757 }
1758 elseif category == "PowerGainOther" then list = {
1759 "POWERGAINOTHEROTHER",
1760 "POWERGAINOTHERSELF",
1761 }
1762 elseif category == "PerformOther" then list = {
1763 "OPEN_LOCK_OTHER",
1764 "SIMPLEPERFORMOTHEROTHER",
1765 "SIMPLEPERFORMOTHERSELF",
1766 "SPELLTERSEPERFORM_OTHER",
1767 }
1768 elseif category == "PerformSelf" then list = {
1769 "OPEN_LOCK_SELF",
1770 "SIMPLEPERFORMSELFOTHER",
1771 "SIMPLEPERFORMSELFSELF",
1772 "SPELLTERSEPERFORM_SELF",
1773 }
1774 elseif category == "ProcResistOther" then list = {
1775 "PROCRESISTOTHEROTHER",
1776 "PROCRESISTOTHERSELF",
1777 }
1778 elseif category == "ProcResistSelf" then list = {
1779 "PROCRESISTSELFOTHER",
1780 "PROCRESISTSELFSELF",
1781 }
1782 elseif category == "EnvOther" then list = {
1783 "VSENVIRONMENTALDAMAGE_DROWNING_OTHER",
1784 "VSENVIRONMENTALDAMAGE_FALLING_OTHER",
1785 "VSENVIRONMENTALDAMAGE_FATIGUE_OTHER",
1786 "VSENVIRONMENTALDAMAGE_FIRE_OTHER",
1787 "VSENVIRONMENTALDAMAGE_LAVA_OTHER",
1788 "VSENVIRONMENTALDAMAGE_SLIME_OTHER",
1789 }
1790 elseif category == "EnvSelf" then list = {
1791 "VSENVIRONMENTALDAMAGE_DROWNING_SELF",
1792 "VSENVIRONMENTALDAMAGE_FALLING_SELF",
1793 "VSENVIRONMENTALDAMAGE_FATIGUE_SELF",
1794 "VSENVIRONMENTALDAMAGE_FIRE_SELF",
1795 "VSENVIRONMENTALDAMAGE_LAVA_SELF",
1796 "VSENVIRONMENTALDAMAGE_SLIME_SELF",
1797 }
1798 -- HoT effects on others. (not casted by others)
1799 elseif category == "HotOther" then list = {
1800 "PERIODICAURAHEALOTHEROTHER",
1801 "PERIODICAURAHEALSELFOTHER",
1802 }
1803 -- HoT effects on you. (not casted by you)
1804 elseif category == "HotSelf" then list = {
1805 "PERIODICAURAHEALSELFSELF",
1806 "PERIODICAURAHEALOTHERSELF",
1807 }
1808 elseif category == "PowerGainSelf" then list = {
1809 "POWERGAINSELFSELF",
1810 "POWERGAINSELFOTHER",
1811 }
1812 elseif category == "BuffOther" then list = {
1813 "AURAAPPLICATIONADDEDOTHERHELPFUL",
1814 "AURAADDEDOTHERHELPFUL",
1815 }
1816 elseif category == "BuffSelf" then list = {
1817 "AURAADDEDSELFHELPFUL",
1818 "AURAAPPLICATIONADDEDSELFHELPFUL",
1819 }
1820 elseif category == "DrainSelf" then list = {
1821 "SPELLPOWERLEECHSELFOTHER",
1822 "SPELLPOWERDRAINSELFOTHER",
1823 "SPELLPOWERDRAINSELFSELF",
1824 }
1825 elseif category == "DrainOther" then list = {
1826 "SPELLPOWERLEECHOTHEROTHER",
1827 "SPELLPOWERLEECHOTHERSELF",
1828 "SPELLPOWERDRAINOTHEROTHER",
1829 "SPELLPOWERDRAINOTHERSELF",
1830 }
1831 -- DoT effects on others (not casted by others)
1832 elseif category == "DotOther" then list = {
1833 "PERIODICAURADAMAGEOTHEROTHER",
1834 "PERIODICAURADAMAGESELFOTHER",
1835 }
1836 -- DoT effects on you (not casted by you)
1837 elseif category == "DotSelf" then list = {
1838 "PERIODICAURADAMAGEOTHERSELF",
1839 "PERIODICAURADAMAGESELFSELF",
1840 }
1841 elseif category == "SpellHitOther" then list = {
1842 "SPELLLOGCRITOTHEROTHER",
1843 "SPELLLOGCRITOTHERSELF",
1844 "SPELLLOGCRITSCHOOLOTHEROTHER",
1845 "SPELLLOGCRITSCHOOLOTHERSELF",
1846 "SPELLLOGOTHEROTHER",
1847 "SPELLLOGOTHERSELF",
1848 "SPELLLOGSCHOOLOTHEROTHER",
1849 "SPELLLOGSCHOOLOTHERSELF",
1850 }
1851 elseif category == "SpellHitSelf" then list = {
1852 "SPELLLOGCRITSELFOTHER",
1853 "SPELLLOGCRITSELFSELF",
1854 "SPELLLOGCRITSCHOOLSELFOTHER",
1855 "SPELLLOGCRITSCHOOLSELFSELF",
1856 "SPELLLOGSELFOTHER",
1857 "SPELLLOGSELFSELF",
1858 "SPELLLOGSCHOOLSELFOTHER",
1859 "SPELLLOGSCHOOLSELFSELF",
1860 }
1861 elseif category == "SpellMissSelf" then list = {
1862 "IMMUNESPELLSELFOTHER",
1863 "IMMUNESPELLSELFSELF",
1864 "SPELLBLOCKEDSELFOTHER",
1865 "SPELLDEFLECTEDSELFOTHER",
1866 "SPELLDEFLECTEDSELFSELF",
1867 "SPELLDODGEDSELFOTHER",
1868 "SPELLDODGEDSELFSELF",
1869 "SPELLEVADEDSELFOTHER",
1870 "SPELLEVADEDSELFSELF",
1871 "SPELLIMMUNESELFOTHER",
1872 "SPELLIMMUNESELFSELF",
1873 "SPELLLOGABSORBSELFOTHER",
1874 "SPELLLOGABSORBSELFSELF",
1875 "SPELLMISSSELFOTHER",
1876 "SPELLMISSSELFSELF",
1877 "SPELLPARRIEDSELFOTHER",
1878 "SPELLPARRIEDSELFSELF",
1879 "SPELLREFLECTSELFOTHER",
1880 "SPELLREFLECTSELFSELF",
1881 "SPELLRESISTSELFOTHER",
1882 "SPELLRESISTSELFSELF",
1883 }
1884 elseif category == "SpellMissOther" then list = {
1885 "IMMUNESPELLOTHEROTHER",
1886 "IMMUNESPELLOTHERSELF",
1887 "SPELLBLOCKEDOTHEROTHER",
1888 "SPELLBLOCKEDOTHERSELF",
1889 "SPELLDODGEDOTHEROTHER",
1890 "SPELLDODGEDOTHERSELF",
1891 "SPELLDEFLECTEDOTHEROTHER",
1892 "SPELLDEFLECTEDOTHERSELF",
1893 "SPELLEVADEDOTHEROTHER",
1894 "SPELLEVADEDOTHERSELF",
1895 "SPELLIMMUNEOTHEROTHER",
1896 "SPELLIMMUNEOTHERSELF",
1897 "SPELLLOGABSORBOTHEROTHER",
1898 "SPELLLOGABSORBOTHERSELF",
1899 "SPELLMISSOTHEROTHER",
1900 "SPELLMISSOTHERSELF",
1901 "SPELLPARRIEDOTHEROTHER",
1902 "SPELLPARRIEDOTHERSELF",
1903 "SPELLREFLECTOTHEROTHER",
1904 "SPELLREFLECTOTHERSELF",
1905 "SPELLRESISTOTHEROTHER",
1906 "SPELLRESISTOTHERSELF",
1907 }
1908 elseif category == "InterruptOther" then list = {
1909 "SPELLINTERRUPTOTHEROTHER",
1910 "SPELLINTERRUPTOTHERSELF",
1911 }
1912 elseif category == "InterruptSelf" then list = {
1913 "SPELLINTERRUPTSELFOTHER",
1914 }
1915 elseif category == "SplitDamageOther" then list = {
1916 "SPELLSPLITDAMAGEOTHEROTHER",
1917 "SPELLSPLITDAMAGEOTHERSELF",
1918 }
1919 else return { category }
1920 end
1921  
1922 return list
1923  
1924 end
1925  
1926 -- Load categories recursively. First layer will not be sorted.
1927 function lib:LoadPatternCategoryTree(catTree, reSort)
1928 if type(catTree) ~= "table" then return end
1929  
1930 local resultList = {}
1931 local list
1932  
1933 for i, v in catTree do
1934  
1935 if type(v) == "table" then
1936 list = self:LoadPatternCategoryTree(v, true)
1937 else -- should be string.
1938 list = self:LoadPatternCategory(v)
1939 table.sort(list, PatternCompare)
1940 end
1941  
1942 for j, w in list do
1943 table.insert(resultList, w)
1944 end
1945  
1946 end
1947  
1948 if reSort then
1949 table.sort(resultList, PatternCompare)
1950 end
1951  
1952 return resultList
1953  
1954  
1955 end
1956  
1957 -- Used to load patternTable elements on demand.
1958 function lib:LoadPatternInfo(patternName)
1959  
1960 local patternInfo
1961  
1962 if patternName == "AURAADDEDOTHERHELPFUL" then
1963 patternInfo = { "buff", 1, 2, nil, }
1964 elseif patternName == "AURAADDEDSELFHELPFUL" then
1965 patternInfo = { "buff", ParserLib_SELF, 1, nil, }
1966 elseif patternName == "AURAAPPLICATIONADDEDOTHERHELPFUL" then
1967 patternInfo = { "buff", 1, 2, 3, }
1968 elseif patternName == "AURAAPPLICATIONADDEDSELFHELPFUL" then
1969 patternInfo = { "buff", ParserLib_SELF, 1, 2, }
1970  
1971 elseif patternName == "OPEN_LOCK_OTHER" then
1972 patternInfo = { "cast", 1, 2, 3, nil, true, }
1973 elseif patternName == "OPEN_LOCK_SELF" then
1974 patternInfo = { "cast", ParserLib_SELF, 1, 2, nil, true, }
1975 elseif patternName == "SIMPLECASTOTHEROTHER" then
1976 patternInfo = { "cast", 1, 2, 3, nil, nil, }
1977 elseif patternName == "SIMPLECASTOTHERSELF" then
1978 patternInfo = { "cast", 1, 2, ParserLib_SELF, nil, nil, }
1979 elseif patternName == "SIMPLECASTSELFOTHER" then
1980 patternInfo = { "cast", ParserLib_SELF, 1, 2, nil, nil, }
1981 elseif patternName == "SIMPLECASTSELFSELF" then
1982 patternInfo = { "cast", ParserLib_SELF, 1, ParserLib_SELF, nil, nil, }
1983 elseif patternName == "SIMPLEPERFORMOTHEROTHER" then
1984 patternInfo = { "cast", 1, 2, 3, nil, true, }
1985 elseif patternName == "SIMPLEPERFORMOTHERSELF" then
1986 patternInfo = { "cast", 1, 2, ParserLib_SELF, nil, true, }
1987 elseif patternName == "SIMPLEPERFORMSELFOTHER" then
1988 patternInfo = { "cast", ParserLib_SELF, 1, 2, nil, true, }
1989 elseif patternName == "SIMPLEPERFORMSELFSELF" then
1990 patternInfo = { "cast", ParserLib_SELF, 1, ParserLib_SELF, nil, true, }
1991 elseif patternName == "SPELLCASTOTHERSTART" then
1992 patternInfo = { "cast", 1, 2, nil, true, nil, }
1993 elseif patternName == "SPELLCASTSELFSTART" then
1994 patternInfo = { "cast", ParserLib_SELF, 1, nil, true, nil, }
1995 elseif patternName == "SPELLPERFORMOTHERSTART" then
1996 patternInfo = { "cast", 1, 2, nil, true, true, }
1997 elseif patternName == "SPELLPERFORMSELFSTART" then
1998 patternInfo = { "cast", ParserLib_SELF, 1, nil, true, true, }
1999 elseif patternName == "SPELLTERSEPERFORM_OTHER" then
2000 patternInfo = { "cast", 1, 2, nil, nil, true, }
2001 elseif patternName == "SPELLTERSEPERFORM_SELF" then
2002 patternInfo = { "cast", ParserLib_SELF, 1, nil, nil, true, }
2003 elseif patternName == "SPELLTERSE_OTHER" then
2004 patternInfo = { "cast", 1, 2, nil, nil, nil, }
2005 elseif patternName == "SPELLTERSE_SELF" then
2006 patternInfo = { "cast", ParserLib_SELF, 1, nil, nil, nil, }
2007  
2008 elseif patternName == "TRADESKILL_LOG_FIRSTPERSON" then
2009 patternInfo = { "create", ParserLib_SELF, 1, }
2010 elseif patternName == "TRADESKILL_LOG_THIRDPERSON" then
2011 patternInfo = { "create", 1, 2, }
2012  
2013 elseif patternName == "PARTYKILLOTHER" then
2014 patternInfo = { "death", 1, 2, nil, nil, }
2015 elseif patternName == "SELFKILLOTHER" then
2016 patternInfo = { "death", 1, ParserLib_SELF, nil, nil, }
2017 elseif patternName == "UNITDESTROYEDOTHER" then
2018 patternInfo = { "death", 1, nil, nil, true, }
2019 elseif patternName == "UNITDIESOTHER" then
2020 patternInfo = { "death", 1, nil, nil, nil, }
2021 elseif patternName == "UNITDIESSELF" then
2022 patternInfo = { "death", ParserLib_SELF, nil, nil, nil, }
2023 elseif patternName == "INSTAKILLOTHER" then
2024 patternInfo = { "death", 1, nil, 2, nil, }
2025 elseif patternName == "INSTAKILLSELF" then
2026 patternInfo = { "death", ParserLib_SELF, nil, true, nil }
2027  
2028  
2029 elseif patternName == "AURAADDEDOTHERHARMFUL" then
2030 patternInfo = { "debuff", 1, 2, nil, }
2031 elseif patternName == "AURAADDEDSELFHARMFUL" then
2032 patternInfo = { "debuff", ParserLib_SELF, 1, nil, }
2033 elseif patternName == "AURAAPPLICATIONADDEDOTHERHARMFUL" then
2034 patternInfo = { "debuff", 1, 2, 3, }
2035 elseif patternName == "AURAAPPLICATIONADDEDSELFHARMFUL" then
2036 patternInfo = { "debuff", ParserLib_SELF, 1, 2, }
2037  
2038 elseif patternName == "AURADISPELOTHER" then
2039 patternInfo = { "dispel", 1, 2, nil, nil, }
2040 elseif patternName == "AURADISPELSELF" then
2041 patternInfo = { "dispel", ParserLib_SELF, 1, nil, nil, }
2042 elseif patternName == "DISPELFAILEDOTHEROTHER" then
2043 patternInfo = { "dispel", 2, 3, 1, true, }
2044 elseif patternName == "DISPELFAILEDOTHERSELF" then
2045 patternInfo = { "dispel", ParserLib_SELF, 2, 1, true, }
2046 elseif patternName == "DISPELFAILEDSELFOTHER" then
2047 patternInfo = { "dispel", 1, 2, ParserLib_SELF, true, }
2048 elseif patternName == "DISPELFAILEDSELFSELF" then
2049 patternInfo = { "dispel", ParserLib_SELF, 1, ParserLib_SELF, true, }
2050  
2051 elseif patternName == "SPELLPOWERDRAINOTHEROTHER" then
2052 patternInfo = { "drain", 1, 5, 2, 3, 4, }
2053 elseif patternName == "SPELLPOWERDRAINOTHERSELF" then
2054 patternInfo = { "drain", 1, ParserLib_SELF, 2, 3, 4, }
2055 elseif patternName == "SPELLPOWERDRAINSELFOTHER" then
2056 patternInfo = { "drain", ParserLib_SELF, 4, 1, 2, 3, }
2057 elseif patternName == "SPELLPOWERDRAINSELFSELF" then
2058 patternInfo = { "drain", ParserLib_SELF, ParserLib_SELF, 1, 2, 3, }
2059  
2060 elseif patternName == "SPELLDURABILITYDAMAGEALLOTHEROTHER" then
2061 patternInfo = { "durability", 1, 2, 3, nil, }
2062 elseif patternName == "SPELLDURABILITYDAMAGEALLOTHERSELF" then
2063 patternInfo = { "durability", 1, 2, ParserLib_SELF, nil, }
2064 elseif patternName == "SPELLDURABILITYDAMAGEALLSELFOTHER" then
2065 patternInfo = { "durability", ParserLib_SELF, 1, 2, nil, }
2066 elseif patternName == "SPELLDURABILITYDAMAGEOTHEROTHER" then
2067 patternInfo = { "durability", 1, 2, 3, 4, }
2068 elseif patternName == "SPELLDURABILITYDAMAGEOTHERSELF" then
2069 patternInfo = { "durability", 1, 2, ParserLib_SELF, 3, }
2070 elseif patternName == "SPELLDURABILITYDAMAGESELFOTHER" then
2071 patternInfo = { "durability", ParserLib_SELF, 1, 2, 3, }
2072  
2073 elseif patternName == "ITEMENCHANTMENTADDOTHEROTHER" then
2074 patternInfo = { "enchant", 1, 3, 2, 4, }
2075 elseif patternName == "ITEMENCHANTMENTADDOTHERSELF" then
2076 patternInfo = { "enchant", 1, ParserLib_SELF, 2, 3, }
2077 elseif patternName == "ITEMENCHANTMENTADDSELFOTHER" then
2078 patternInfo = { "enchant", ParserLib_SELF, 2, 1, 3, }
2079 elseif patternName == "ITEMENCHANTMENTADDSELFSELF" then
2080 patternInfo = { "enchant", ParserLib_SELF, ParserLib_SELF, 1, 2, }
2081  
2082 elseif patternName == "VSENVIRONMENTALDAMAGE_DROWNING_OTHER" then
2083 patternInfo = { "environment", 1, 2, "drown", }
2084 elseif patternName == "VSENVIRONMENTALDAMAGE_DROWNING_SELF" then
2085 patternInfo = { "environment", ParserLib_SELF, 1, "drown", }
2086 elseif patternName == "VSENVIRONMENTALDAMAGE_FALLING_OTHER" then
2087 patternInfo = { "environment", 1, 2, "fall", }
2088 elseif patternName == "VSENVIRONMENTALDAMAGE_FALLING_SELF" then
2089 patternInfo = { "environment", ParserLib_SELF, 1, "fall", }
2090 elseif patternName == "VSENVIRONMENTALDAMAGE_FATIGUE_OTHER" then
2091 patternInfo = { "environment", 1, 2, "exhaust", }
2092 elseif patternName == "VSENVIRONMENTALDAMAGE_FATIGUE_SELF" then
2093 patternInfo = { "environment", ParserLib_SELF, 1, "exhaust", }
2094 elseif patternName == "VSENVIRONMENTALDAMAGE_FIRE_OTHER" then
2095 patternInfo = { "environment", 1, 2, "fire", }
2096 elseif patternName == "VSENVIRONMENTALDAMAGE_FIRE_SELF" then
2097 patternInfo = { "environment", ParserLib_SELF, 1, "fire", }
2098 elseif patternName == "VSENVIRONMENTALDAMAGE_LAVA_OTHER" then
2099 patternInfo = { "environment", 1, 2, "lava", }
2100 elseif patternName == "VSENVIRONMENTALDAMAGE_LAVA_SELF" then
2101 patternInfo = { "environment", ParserLib_SELF, 1, "lava", }
2102 elseif patternName == "VSENVIRONMENTALDAMAGE_SLIME_OTHER" then
2103 patternInfo = { "environment", 1, 2, "slime", }
2104 elseif patternName == "VSENVIRONMENTALDAMAGE_SLIME_SELF" then
2105 patternInfo = { "environment", ParserLib_SELF, 1, "slime", }
2106  
2107 elseif patternName == "COMBATLOG_XPGAIN" then
2108 patternInfo = { "experience", 2, nil, nil, nil, nil, nil, nil, nil, 1, }
2109 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION1" then
2110 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, nil, nil, nil, }
2111 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION1_GROUP" then
2112 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, nil, 5, nil, }
2113 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION1_RAID" then
2114 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, 5, nil, nil, }
2115 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION2" then
2116 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, nil, nil, nil, }
2117 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION2_GROUP" then
2118 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, nil, 5, nil, }
2119 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION2_RAID" then
2120 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, 5, nil, nil, }
2121 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION4" then
2122 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, nil, nil, nil, }
2123 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION4_GROUP" then
2124 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, nil, 5, nil, }
2125 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION4_RAID" then
2126 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, 5, nil, nil, }
2127 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION5" then
2128 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, nil, nil, nil, }
2129 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION5_GROUP" then
2130 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, nil, 5, nil, }
2131 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION5_RAID" then
2132 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, 5, nil, nil, }
2133 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON" then
2134 patternInfo = { "experience", 2, 1, nil, nil, nil, nil, nil, nil, nil, }
2135 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_GROUP" then
2136 patternInfo = { "experience", 2, 1, nil, nil, nil, nil, nil, 3, nil, }
2137 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_RAID" then
2138 patternInfo = { "experience", 2, 1, nil, nil, nil, nil, 3, nil, nil, }
2139 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED" then
2140 patternInfo = { "experience", 1, nil, nil, nil, nil, nil, nil, nil, nil, }
2141 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_GROUP" then
2142 patternInfo = { "experience", 1, nil, nil, nil, nil, nil, nil, 2, nil, }
2143 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_RAID" then
2144 patternInfo = { "experience", 1, nil, nil, nil, nil, nil, 2, nil, nil, }
2145 elseif patternName == "COMBATLOG_XPLOSS_FIRSTPERSON_UNNAMED" then
2146 patternInfo = { "experience", 1, nil, nil, nil, nil, nil, nil, nil, nil, }
2147  
2148 elseif patternName == "SPELLEXTRAATTACKSOTHER" then
2149 patternInfo = { "extraattack", 1, 3, 2, }
2150 elseif patternName == "SPELLEXTRAATTACKSOTHER_SINGULAR" then
2151 patternInfo = { "extraattack", 1, 3, 2, }
2152 elseif patternName == "SPELLEXTRAATTACKSSELF" then
2153 patternInfo = { "extraattack", ParserLib_SELF, 2, 1, }
2154 elseif patternName == "SPELLEXTRAATTACKSSELF_SINGULAR" then
2155 patternInfo = { "extraattack", ParserLib_SELF, 2, 1, }
2156  
2157 elseif patternName == "AURAREMOVEDOTHER" then
2158 patternInfo = { "fade", 2, 1, }
2159 elseif patternName == "AURAREMOVEDSELF" then
2160 patternInfo = { "fade", ParserLib_SELF, 1, }
2161  
2162 elseif patternName == "SPELLFAILCASTSELF" then
2163 patternInfo = { "fail", ParserLib_SELF, 1, 2, }
2164 elseif patternName == "SPELLFAILPERFORMSELF" then
2165 patternInfo = { "fail", ParserLib_SELF, 1, 2, }
2166  
2167 elseif patternName == "FEEDPET_LOG_FIRSTPERSON" then
2168 patternInfo = { "feedpet", ParserLib_SELF, 1, }
2169 elseif patternName == "FEEDPET_LOG_THIRDPERSON" then
2170 patternInfo = { "feedpet", 1, 2, }
2171  
2172 elseif patternName == "POWERGAINOTHEROTHER" then
2173 patternInfo = { "gain", 4, 1, 5, 2, 3, }
2174 elseif patternName == "POWERGAINOTHERSELF" then
2175 patternInfo = { "gain", 3, ParserLib_SELF, 4, 1, 2, }
2176 elseif patternName == "POWERGAINSELFOTHER" then
2177 patternInfo = { "gain", ParserLib_SELF, 1, 4, 2, 3, }
2178 elseif patternName == "POWERGAINSELFSELF" then
2179 patternInfo = { "gain", ParserLib_SELF, ParserLib_SELF, 3, 1, 2, }
2180  
2181 elseif patternName == "HEALEDCRITOTHEROTHER" then
2182 patternInfo = { "heal", 1, 3, 2, 4, true, nil, }
2183 elseif patternName == "HEALEDCRITOTHERSELF" then
2184 patternInfo = { "heal", 1, ParserLib_SELF, 2, 3, true, nil, }
2185 elseif patternName == "HEALEDCRITSELFOTHER" then
2186 patternInfo = { "heal", ParserLib_SELF, 2, 1, 3, true, nil, }
2187 elseif patternName == "HEALEDCRITSELFSELF" then
2188 patternInfo = { "heal", ParserLib_SELF, ParserLib_SELF, 1, 2, true, nil, }
2189 elseif patternName == "HEALEDOTHEROTHER" then
2190 patternInfo = { "heal", 1, 3, 2, 4, nil, nil, }
2191 elseif patternName == "HEALEDOTHERSELF" then
2192 patternInfo = { "heal", 1, ParserLib_SELF, 2, 3, nil, nil, }
2193 elseif patternName == "HEALEDSELFOTHER" then
2194 patternInfo = { "heal", ParserLib_SELF, 2, 1, 3, nil, nil, }
2195 elseif patternName == "HEALEDSELFSELF" then
2196 patternInfo = { "heal", ParserLib_SELF, ParserLib_SELF, 1, 2, nil, nil, }
2197 elseif patternName == "PERIODICAURAHEALOTHEROTHER" then
2198 patternInfo = { "heal", 3, 1, 4, 2, nil, true, }
2199 elseif patternName == "PERIODICAURAHEALOTHERSELF" then
2200 patternInfo = { "heal", 2, ParserLib_SELF, 3, 1, nil, true, }
2201 elseif patternName == "PERIODICAURAHEALSELFOTHER" then
2202 patternInfo = { "heal", ParserLib_SELF, 1, 3, 2, nil, true, }
2203 elseif patternName == "PERIODICAURAHEALSELFSELF" then
2204 patternInfo = { "heal", ParserLib_SELF, ParserLib_SELF, 2, 1, nil, true, }
2205  
2206 elseif patternName == "COMBATHITCRITOTHEROTHER" then
2207 patternInfo = { "hit", 1, 2, ParserLib_MELEE, 3, nil, true, nil, nil, }
2208 elseif patternName == "COMBATHITCRITOTHERSELF" then
2209 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_MELEE, 2, nil, true, nil, nil, }
2210 elseif patternName == "COMBATHITCRITSCHOOLOTHEROTHER" then
2211 patternInfo = { "hit", 1, 2, ParserLib_MELEE, 3, 4, true, nil, nil, }
2212 elseif patternName == "COMBATHITCRITSCHOOLOTHERSELF" then
2213 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_MELEE, 2, 3, true, nil, nil, }
2214 elseif patternName == "COMBATHITCRITSCHOOLSELFOTHER" then
2215 patternInfo = { "hit", ParserLib_SELF, 1, ParserLib_MELEE, 2, 3, true, nil, nil, }
2216 elseif patternName == "COMBATHITCRITSELFOTHER" then
2217 patternInfo = { "hit", ParserLib_SELF, 1, ParserLib_MELEE, 2, nil, true, nil, nil, }
2218 elseif patternName == "COMBATHITOTHEROTHER" then
2219 patternInfo = { "hit", 1, 2, ParserLib_MELEE, 3, nil, nil, nil, nil, }
2220 elseif patternName == "COMBATHITOTHERSELF" then
2221 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_MELEE, 2, nil, nil, nil, nil, }
2222 elseif patternName == "COMBATHITSCHOOLOTHEROTHER" then
2223 patternInfo = { "hit", 1, 2, ParserLib_MELEE, 3, 4, nil, nil, nil, }
2224 elseif patternName == "COMBATHITSCHOOLOTHERSELF" then
2225 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_MELEE, 2, 3, nil, nil, nil, }
2226 elseif patternName == "COMBATHITSCHOOLSELFOTHER" then
2227 patternInfo = { "hit", ParserLib_SELF, 1, ParserLib_MELEE, 2, 3, nil, nil, nil, }
2228 elseif patternName == "COMBATHITSELFOTHER" then
2229 patternInfo = { "hit", ParserLib_SELF, 1, ParserLib_MELEE, 2, nil, nil, nil, nil, }
2230 elseif patternName == "DAMAGESHIELDOTHEROTHER" then
2231 patternInfo = { "hit", 1, 4, ParserLib_DAMAGESHIELD, 2, 3, nil, nil, nil, }
2232 elseif patternName == "DAMAGESHIELDOTHERSELF" then
2233 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_DAMAGESHIELD, 2, 3, nil, nil, nil, }
2234 elseif patternName == "DAMAGESHIELDSELFOTHER" then
2235 patternInfo = { "hit", ParserLib_SELF, 3, ParserLib_DAMAGESHIELD, 1, 2, nil, nil, nil, }
2236 elseif patternName == "PERIODICAURADAMAGEOTHEROTHER" then
2237 patternInfo = { "hit", 4, 1, 5, 2, 3, nil, true, nil, }
2238 elseif patternName == "PERIODICAURADAMAGEOTHERSELF" then
2239 patternInfo = { "hit", 3, ParserLib_SELF, 4, 1, 2, nil, true, nil, }
2240 elseif patternName == "PERIODICAURADAMAGESELFOTHER" then
2241 patternInfo = { "hit", ParserLib_SELF, 1, 4, 2, 3, nil, true, nil, }
2242 elseif patternName == "PERIODICAURADAMAGESELFSELF" then
2243 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 3, 1, 2, nil, true, nil, }
2244 elseif patternName == "SPELLLOGCRITOTHEROTHER" then
2245 patternInfo = { "hit", 1, 3, 2, 4, nil, true, nil, nil, }
2246 elseif patternName == "SPELLLOGCRITOTHERSELF" then
2247 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, nil, true, nil, nil, }
2248 elseif patternName == "SPELLLOGCRITSCHOOLOTHEROTHER" then
2249 patternInfo = { "hit", 1, 3, 2, 4, 5, true, nil, nil, }
2250 elseif patternName == "SPELLLOGCRITSCHOOLOTHERSELF" then
2251 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, 4, true, nil, nil, }
2252 elseif patternName == "SPELLLOGCRITSCHOOLSELFOTHER" then
2253 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, 4, true, nil, nil, }
2254 elseif patternName == "SPELLLOGCRITSCHOOLSELFSELF" then
2255 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 1, 2, 3, true, nil, nil, }
2256 elseif patternName == "SPELLLOGCRITSELFOTHER" then
2257 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, nil, true, nil, nil, }
2258 elseif patternName == "SPELLLOGCRITSELFSELF" then
2259 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 1, 2, nil, true, nil, nil, }
2260 elseif patternName == "SPELLLOGOTHEROTHER" then
2261 patternInfo = { "hit", 1, 3, 2, 4, nil, nil, nil, nil, }
2262 elseif patternName == "SPELLLOGOTHERSELF" then
2263 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, nil, nil, nil, nil, }
2264 elseif patternName == "SPELLLOGSCHOOLOTHEROTHER" then
2265 patternInfo = { "hit", 1, 3, 2, 4, 5, nil, nil, nil, }
2266 elseif patternName == "SPELLLOGSCHOOLOTHERSELF" then
2267 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, 4, nil, nil, nil, }
2268 elseif patternName == "SPELLLOGSCHOOLSELFOTHER" then
2269 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, 4, nil, nil, nil, }
2270 elseif patternName == "SPELLLOGSCHOOLSELFSELF" then
2271 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 1, 2, 3, nil, nil, nil, }
2272 elseif patternName == "SPELLLOGSELFOTHER" then
2273 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, nil, nil, nil, nil, }
2274 elseif patternName == "SPELLLOGSELFSELF" then
2275 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 1, 2, nil, nil, nil, nil, }
2276 elseif patternName == "SPELLSPLITDAMAGEOTHEROTHER" then
2277 patternInfo = { "hit", 1, 3, 2, 4, nil, nil, nil, true, }
2278 elseif patternName == "SPELLSPLITDAMAGEOTHERSELF" then
2279 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, nil, nil, nil, true, }
2280 elseif patternName == "SPELLSPLITDAMAGESELFOTHER" then
2281 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, nil, nil, nil, true, }
2282  
2283 elseif patternName == "COMBATLOG_DISHONORGAIN" then
2284 patternInfo = { "honor", nil, 1, nil, }
2285 elseif patternName == "COMBATLOG_HONORAWARD" then
2286 patternInfo = { "honor", 1, nil, nil, }
2287 elseif patternName == "COMBATLOG_HONORGAIN" then
2288 patternInfo = { "honor", 3, 1, 2, }
2289  
2290 elseif patternName == "SPELLINTERRUPTOTHEROTHER" then
2291 patternInfo = { "interrupt", 1, 2, 3, }
2292 elseif patternName == "SPELLINTERRUPTOTHERSELF" then
2293 patternInfo = { "interrupt", 1, ParserLib_SELF, 2, }
2294 elseif patternName == "SPELLINTERRUPTSELFOTHER" then
2295 patternInfo = { "interrupt", ParserLib_SELF, 1, 2, }
2296  
2297 elseif patternName == "SPELLPOWERLEECHOTHEROTHER" then
2298 patternInfo = { "leech", 1, 5, 2, 3, 4, 6, 7, 8, }
2299 elseif patternName == "SPELLPOWERLEECHOTHERSELF" then
2300 patternInfo = { "leech", 1, ParserLib_SELF, 2, 3, 4, 5, 6, 7, }
2301 elseif patternName == "SPELLPOWERLEECHSELFOTHER" then
2302 patternInfo = { "leech", ParserLib_SELF, 4, 1, 2, 3, ParserLib_SELF, 5, 6, }
2303  
2304 elseif patternName == "IMMUNEDAMAGECLASSOTHEROTHER" then
2305 patternInfo = { "miss", 2, 1, ParserLib_MELEE, "immune", }
2306 elseif patternName == "IMMUNEDAMAGECLASSOTHERSELF" then
2307 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "immune", }
2308 elseif patternName == "IMMUNEDAMAGECLASSSELFOTHER" then
2309 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "immune", }
2310 elseif patternName == "IMMUNEOTHEROTHER" then
2311 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "immune", }
2312 elseif patternName == "IMMUNEOTHERSELF" then
2313 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "immune", }
2314 elseif patternName == "IMMUNESELFOTHER" then
2315 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "immune", }
2316 elseif patternName == "IMMUNESELFSELF" then
2317 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, ParserLib_MELEE, "immune", }
2318 elseif patternName == "IMMUNESPELLOTHEROTHER" then
2319 patternInfo = { "miss", 2, 1, 3, "immune", }
2320 elseif patternName == "IMMUNESPELLOTHERSELF" then
2321 patternInfo = { "miss", 1, ParserLib_SELF, 2, "immune", }
2322 elseif patternName == "IMMUNESPELLSELFOTHER" then
2323 patternInfo = { "miss", ParserLib_SELF, 1, 2, "immune", }
2324 elseif patternName == "IMMUNESPELLSELFSELF" then
2325 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "immune", }
2326 elseif patternName == "MISSEDOTHEROTHER" then
2327 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "miss", }
2328 elseif patternName == "MISSEDOTHERSELF" then
2329 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "miss", }
2330 elseif patternName == "MISSEDSELFOTHER" then
2331 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "miss", }
2332 elseif patternName == "PROCRESISTOTHEROTHER" then
2333 patternInfo = { "miss", 2, 1, 3, "resist", }
2334 elseif patternName == "PROCRESISTOTHERSELF" then
2335 patternInfo = { "miss", 1, ParserLib_SELF, 2, "resist", }
2336 elseif patternName == "PROCRESISTSELFOTHER" then
2337 patternInfo = { "miss", ParserLib_SELF, 1, 2, "resist", }
2338 elseif patternName == "PROCRESISTSELFSELF" then
2339 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "resist", }
2340 elseif patternName == "SPELLBLOCKEDOTHEROTHER" then
2341 patternInfo = { "miss", 1, 3, 2, "block", }
2342 elseif patternName == "SPELLBLOCKEDOTHERSELF" then
2343 patternInfo = { "miss", 1, ParserLib_SELF, 2, "block", }
2344 elseif patternName == "SPELLBLOCKEDSELFOTHER" then
2345 patternInfo = { "miss", ParserLib_SELF, 2, 1, "block", }
2346 elseif patternName == "SPELLDEFLECTEDOTHEROTHER" then
2347 patternInfo = { "miss", 1, 3, 2, "deflect", }
2348 elseif patternName == "SPELLDEFLECTEDOTHERSELF" then
2349 patternInfo = { "miss", 1, ParserLib_SELF, 2, "deflect", }
2350 elseif patternName == "SPELLDEFLECTEDSELFOTHER" then
2351 patternInfo = { "miss", ParserLib_SELF, 2, 1, "deflect", }
2352 elseif patternName == "SPELLDEFLECTEDSELFSELF" then
2353 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "deflect", }
2354 elseif patternName == "SPELLDODGEDOTHEROTHER" then
2355 patternInfo = { "miss", 1, 3, 2, "dodge", }
2356 elseif patternName == "SPELLDODGEDOTHERSELF" then
2357 patternInfo = { "miss", 1, ParserLib_SELF, 2, "dodge", }
2358 elseif patternName == "SPELLDODGEDSELFOTHER" then
2359 patternInfo = { "miss", ParserLib_SELF, 2, 1, "dodge", }
2360 elseif patternName == "SPELLDODGEDSELFSELF" then
2361 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "dodge", }
2362 elseif patternName == "SPELLEVADEDOTHEROTHER" then
2363 patternInfo = { "miss", 1, 3, 2, "evade", }
2364 elseif patternName == "SPELLEVADEDOTHERSELF" then
2365 patternInfo = { "miss", 1, ParserLib_SELF, 2, "evade", }
2366 elseif patternName == "SPELLEVADEDSELFOTHER" then
2367 patternInfo = { "miss", ParserLib_SELF, 2, 1, "evade", }
2368 elseif patternName == "SPELLEVADEDSELFSELF" then
2369 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "evade", }
2370 elseif patternName == "SPELLIMMUNEOTHEROTHER" then
2371 patternInfo = { "miss", 1, 3, 2, "immune", }
2372 elseif patternName == "SPELLIMMUNEOTHERSELF" then
2373 patternInfo = { "miss", 1, ParserLib_SELF, 2, "immune", }
2374 elseif patternName == "SPELLIMMUNESELFOTHER" then
2375 patternInfo = { "miss", ParserLib_SELF, 2, 1, "immune", }
2376 elseif patternName == "SPELLIMMUNESELFSELF" then
2377 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "immune", }
2378 elseif patternName == "SPELLLOGABSORBOTHEROTHER" then
2379 patternInfo = { "miss", 1, 3, 2, "absorb", }
2380 elseif patternName == "SPELLLOGABSORBOTHERSELF" then
2381 patternInfo = { "miss", 1, ParserLib_SELF, 2, "absorb", }
2382 elseif patternName == "SPELLLOGABSORBSELFOTHER" then
2383 patternInfo = { "miss", ParserLib_SELF, 2, 1, "absorb", }
2384 elseif patternName == "SPELLLOGABSORBSELFSELF" then
2385 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "absorb", }
2386 elseif patternName == "SPELLMISSOTHEROTHER" then
2387 patternInfo = { "miss", 1, 3, 2, "miss", }
2388 elseif patternName == "SPELLMISSOTHERSELF" then
2389 patternInfo = { "miss", 1, ParserLib_SELF, 2, "miss", }
2390 elseif patternName == "SPELLMISSSELFOTHER" then
2391 patternInfo = { "miss", ParserLib_SELF, 2, 1, "miss", }
2392 elseif patternName == "SPELLMISSSELFSELF" then
2393 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "miss", }
2394 elseif patternName == "SPELLPARRIEDOTHEROTHER" then
2395 patternInfo = { "miss", 1, 3, 2, "parry", }
2396 elseif patternName == "SPELLPARRIEDOTHERSELF" then
2397 patternInfo = { "miss", 1, ParserLib_SELF, 2, "parry", }
2398 elseif patternName == "SPELLPARRIEDSELFOTHER" then
2399 patternInfo = { "miss", ParserLib_SELF, 2, 1, "parry", }
2400 elseif patternName == "SPELLPARRIEDSELFSELF" then
2401 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "parry", }
2402 elseif patternName == "SPELLREFLECTOTHEROTHER" then
2403 patternInfo = { "miss", 1, 3, 2, "reflect", }
2404 elseif patternName == "SPELLREFLECTOTHERSELF" then
2405 patternInfo = { "miss", 1, ParserLib_SELF, 2, "reflect", }
2406 elseif patternName == "SPELLREFLECTSELFOTHER" then
2407 patternInfo = { "miss", ParserLib_SELF, 2, 1, "reflect", }
2408 elseif patternName == "SPELLREFLECTSELFSELF" then
2409 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "reflect", }
2410 elseif patternName == "SPELLRESISTOTHEROTHER" then
2411 patternInfo = { "miss", 1, 3, 2, "resist", }
2412 elseif patternName == "SPELLRESISTOTHERSELF" then
2413 patternInfo = { "miss", 1, ParserLib_SELF, 2, "resist", }
2414 elseif patternName == "SPELLRESISTSELFOTHER" then
2415 patternInfo = { "miss", ParserLib_SELF, 2, 1, "resist", }
2416 elseif patternName == "SPELLRESISTSELFSELF" then
2417 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "resist", }
2418 elseif patternName == "VSABSORBOTHEROTHER" then
2419 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "absorb", }
2420 elseif patternName == "VSABSORBOTHERSELF" then
2421 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "absorb", }
2422 elseif patternName == "VSABSORBSELFOTHER" then
2423 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "absorb", }
2424 elseif patternName == "VSBLOCKOTHEROTHER" then
2425 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "block", }
2426 elseif patternName == "VSBLOCKOTHERSELF" then
2427 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "block", }
2428 elseif patternName == "VSBLOCKSELFOTHER" then
2429 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "block", }
2430 elseif patternName == "VSDEFLECTOTHEROTHER" then
2431 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "deflect", }
2432 elseif patternName == "VSDEFLECTOTHERSELF" then
2433 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "deflect", }
2434 elseif patternName == "VSDEFLECTSELFOTHER" then
2435 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "deflect", }
2436 elseif patternName == "VSDODGEOTHEROTHER" then
2437 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "dodge", }
2438 elseif patternName == "VSDODGEOTHERSELF" then
2439 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "dodge", }
2440 elseif patternName == "VSDODGESELFOTHER" then
2441 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "dodge", }
2442 elseif patternName == "VSEVADEOTHEROTHER" then
2443 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "evade", }
2444 elseif patternName == "VSEVADEOTHERSELF" then
2445 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "evade", }
2446 elseif patternName == "VSEVADESELFOTHER" then
2447 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "evade", }
2448 elseif patternName == "VSIMMUNEOTHEROTHER" then
2449 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "immune", }
2450 elseif patternName == "VSIMMUNEOTHERSELF" then
2451 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "immune", }
2452 elseif patternName == "VSIMMUNESELFOTHER" then
2453 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "immune", }
2454 elseif patternName == "VSPARRYOTHEROTHER" then
2455 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "parry", }
2456 elseif patternName == "VSPARRYOTHERSELF" then
2457 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "parry", }
2458 elseif patternName == "VSPARRYSELFOTHER" then
2459 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "parry", }
2460 elseif patternName == "VSRESISTOTHEROTHER" then
2461 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "resist", }
2462 elseif patternName == "VSRESISTOTHERSELF" then
2463 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "resist", }
2464 elseif patternName == "VSRESISTSELFOTHER" then
2465 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "resist", }
2466  
2467 elseif patternName == "FACTION_STANDING_CHANGED" then
2468 patternInfo = { "reputation", 2, nil, 1, nil, }
2469 elseif patternName == "FACTION_STANDING_DECREASED" then
2470 patternInfo = { "reputation", 1, 2, nil, true, }
2471 elseif patternName == "FACTION_STANDING_INCREASED" then
2472 patternInfo = { "reputation", 1, 2, nil, nil, }
2473 end
2474  
2475 if not patternInfo then
2476 -- self:Print("LoadPatternInfo(): Cannot find " .. patternName ); -- debug
2477 return
2478 end
2479  
2480 local pattern = getglobal(patternName); -- Get the pattern from GlobalStrings.lua
2481  
2482 -- How many regexp tokens in this pattern?
2483 local tc = 0
2484 for _ in string.gfind(pattern, "%%%d?%$?([sd])") do tc = tc + 1 end
2485  
2486 -- Convert string.format tokens into LUA regexp tokens.
2487 pattern = { self:ConvertPattern(pattern, true) }
2488  
2489 local n = table.getn(pattern)
2490 if n > 1 then -- Extra return values are the remapped token sequences.
2491  
2492 for j in patternInfo do
2493 if type(patternInfo[j]) == "number" and patternInfo[j] < 100 then
2494 patternInfo[j] = pattern[patternInfo[j]+1] -- Remap to correct token sequence.
2495 end
2496 end
2497  
2498 end
2499  
2500 patternInfo.tc = tc
2501 patternInfo.pattern = pattern[1]
2502  
2503 return patternInfo
2504  
2505 end
2506  
2507 -- Fields of the patternTable.
2508 lib.infoMap = {
2509 hit = { "source", "victim", "skill", "amount", "element", "isCrit", "isDOT", "isSplit" },
2510 heal = { "source", "victim", "skill", "amount", "isCrit", "isDOT" },
2511 miss = { "source", "victim", "skill", "missType" },
2512 death = { "victim", "source", "skill", "isItem" },
2513 debuff = { "victim", "skill", "amountRank" },
2514 buff = { "victim", "skill", "amountRank" },
2515 fade = { "victim", "skill" },
2516 cast = { "source", "skill", "victim", "isBegin", "isPerform" },
2517 gain = { "source", "victim", "skill", "amount", "attribute" },
2518 drain = { "source", "victim", "skill", "amount", "attribute" },
2519 leech = { "source", "victim", "skill", "amount", "attribute", "sourceGained", "amountGained", "attributeGained" },
2520 dispel = { "victim", "skill", "source", "isFailed" },
2521 extraattack = { "victim", "skill", "amount" },
2522 environment = { "victim", "amount", "damageType" },
2523 experience = { "amount", "source", "bonusAmount", "bonusType", "penaltyAmount", "penaltyType", "amountRaidPenalty", "amountGroupBonus", "victim" },
2524 reputation = { "faction", "amount", "rank", "isNegative" },
2525 feedpet = { "victim", "item" },
2526 enchant = { "source", "victim", "skill", "item" },
2527 fail = { "source", "skill", "reason" },
2528 interrupt = { "source", "victim", "skill" },
2529 create = { "source", "item" },
2530 honor = { "amount", "source", "sourceRank" }, -- if amount == nil then isDishonor = true.
2531 durability = { "source", "skill", "victim", "item" }, -- is not item then isAllItems = true
2532 unknown = { "message" },
2533 }
2534  
2535 function lib:GetInfoFieldName(infoType, fieldIndex)
2536 if self.infoMap[infoType] then
2537 return self.infoMap[infoType][fieldIndex-1] -- Skip the first field in patternTable which is 'type'.
2538 end
2539 end
2540  
2541 --------------------------------
2542 -- Load this bitch! --
2543 --------------------------------
2544 libobj:Register(lib)