vanilla-wow-addons – Blame information for rev 1

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