444 lines
16 KiB
Lua
444 lines
16 KiB
Lua
local parser = ShaguDPS.parser
|
|
|
|
-- sanitize, cache and convert patterns into gfind compatible ones
|
|
local sanitize_cache = {}
|
|
function sanitize(pattern)
|
|
if not sanitize_cache[pattern] then
|
|
local ret = pattern
|
|
-- escape magic characters
|
|
ret = gsub(ret, "([%+%-%*%(%)%?%[%]%^])", "%%%1")
|
|
-- remove capture indexes
|
|
ret = gsub(ret, "%d%$","")
|
|
-- catch all characters
|
|
ret = gsub(ret, "(%%%a)","%(%1+%)")
|
|
-- convert all %s to .+
|
|
ret = gsub(ret, "%%s%+",".+")
|
|
-- set priority to numbers over strings
|
|
ret = gsub(ret, "%(.%+%)%(%%d%+%)","%(.-%)%(%%d%+%)")
|
|
-- cache it
|
|
sanitize_cache[pattern] = ret
|
|
end
|
|
|
|
return sanitize_cache[pattern]
|
|
end
|
|
|
|
-- find, cache and return the indexes of a regex pattern
|
|
local capture_cache = {}
|
|
function captures(pat)
|
|
local r = capture_cache
|
|
if not r[pat] then
|
|
-- set default to nil
|
|
r[pat] = { nil, nil, nil, nil, nil }
|
|
|
|
-- try to find custom capture indexes
|
|
for a, b, c, d, e in string.gfind(gsub(pat, "%((.+)%)", "%1"), gsub(pat, "%d%$", "%%(.-)$")) do
|
|
r[pat][1] = tonumber(a)
|
|
r[pat][2] = tonumber(b)
|
|
r[pat][3] = tonumber(c)
|
|
r[pat][4] = tonumber(d)
|
|
r[pat][5] = tonumber(e)
|
|
end
|
|
end
|
|
|
|
return r[pat][1], r[pat][2], r[pat][3], r[pat][4], r[pat][5]
|
|
end
|
|
|
|
-- same as string.find but aware of up to 5 capture indexes
|
|
local ra, rb, rc, rd, re, a, b, c, d, e, match, num, va, vb, vc, vd, ve
|
|
function cfind(str, pat)
|
|
-- read capture indexes
|
|
a, b, c, d, e = captures(pat)
|
|
match, num, va, vb, vc, vd, ve = string.find(str, sanitize(pat))
|
|
|
|
-- put entries into the proper return values
|
|
ra = e == 1 and ve or d == 1 and vd or c == 1 and vc or b == 1 and vb or va
|
|
rb = e == 2 and ve or d == 2 and vd or c == 2 and vc or a == 2 and va or vb
|
|
rc = e == 3 and ve or d == 3 and vd or a == 3 and va or b == 3 and vb or vc
|
|
rd = e == 4 and ve or a == 4 and va or c == 4 and vc or b == 4 and vb or vd
|
|
re = a == 5 and va or d == 5 and vd or c == 5 and vc or b == 5 and vb or ve
|
|
|
|
return match, num, ra, rb, rc, rd, re
|
|
end
|
|
|
|
-- list of possible combat log patterns that may appear on the same events
|
|
local combatlog_strings = {
|
|
-- Damage
|
|
["Hit Damage (self vs. other)"] = {
|
|
COMBATHITSELFOTHER, COMBATHITSCHOOLSELFOTHER, COMBATHITCRITSELFOTHER, COMBATHITCRITSCHOOLSELFOTHER
|
|
},
|
|
["Hit Damage (other vs. self)"] = {
|
|
COMBATHITOTHERSELF, COMBATHITCRITOTHERSELF, COMBATHITSCHOOLOTHERSELF, COMBATHITCRITSCHOOLOTHERSELF
|
|
},
|
|
["Hit Damage (other vs. other)"] = {
|
|
COMBATHITOTHEROTHER, COMBATHITCRITOTHEROTHER, COMBATHITSCHOOLOTHEROTHER, COMBATHITCRITSCHOOLOTHEROTHER
|
|
},
|
|
["Spell Damage (self vs. self/other)"] = {
|
|
SPELLLOGSCHOOLSELFSELF, SPELLLOGCRITSCHOOLSELFSELF, SPELLLOGSELFSELF, SPELLLOGCRITSELFSELF, SPELLLOGSCHOOLSELFOTHER, SPELLLOGCRITSCHOOLSELFOTHER, SPELLLOGSELFOTHER, SPELLLOGCRITSELFOTHER
|
|
},
|
|
["Spell Damage (other vs. self)"] = {
|
|
SPELLLOGSCHOOLOTHERSELF, SPELLLOGCRITSCHOOLOTHERSELF, SPELLLOGOTHERSELF, SPELLLOGCRITOTHERSELF
|
|
},
|
|
["Spell Damage (other vs. other)"] = {
|
|
SPELLLOGSCHOOLOTHEROTHER, SPELLLOGCRITSCHOOLOTHEROTHER, SPELLLOGOTHEROTHER, SPELLLOGCRITOTHEROTHER
|
|
},
|
|
["Shield Damage (self vs. other)"] = {
|
|
DAMAGESHIELDSELFOTHER
|
|
},
|
|
["Shield Damage (other vs. self/other)"] = {
|
|
DAMAGESHIELDOTHERSELF, DAMAGESHIELDOTHEROTHER
|
|
},
|
|
["Periodic Damage (self/other vs. other)"] = {
|
|
PERIODICAURADAMAGESELFOTHER, PERIODICAURADAMAGEOTHEROTHER
|
|
},
|
|
["Periodic Damage (self/other vs. self)"] = {
|
|
PERIODICAURADAMAGESELFSELF, PERIODICAURADAMAGEOTHERSELF
|
|
},
|
|
|
|
-- Heal
|
|
["Heal (self vs. self/other)"] = {
|
|
HEALEDCRITSELFSELF, HEALEDSELFSELF, HEALEDCRITSELFOTHER, HEALEDSELFOTHER
|
|
},
|
|
["Heal (other vs. self/other)"] = {
|
|
HEALEDCRITOTHERSELF, HEALEDOTHERSELF, HEALEDCRITOTHEROTHER, HEALEDOTHEROTHER
|
|
},
|
|
["Periodic Heal (self/other vs. other)"] = {
|
|
PERIODICAURAHEALSELFOTHER, PERIODICAURAHEALOTHEROTHER
|
|
},
|
|
["Periodic Heal (other vs. self/other)"] = {
|
|
PERIODICAURAHEALSELFSELF, PERIODICAURAHEALOTHERSELF
|
|
}
|
|
}
|
|
|
|
-- list of combat log events with possible patterns assigned to them
|
|
local combatlog_events = {
|
|
-- Damage
|
|
["CHAT_MSG_COMBAT_SELF_HITS"] = combatlog_strings["Hit Damage (self vs. other)"],
|
|
["CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS"] = combatlog_strings["Hit Damage (other vs. self)"],
|
|
["CHAT_MSG_COMBAT_PARTY_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
|
|
["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
|
|
["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
|
|
["CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
|
|
["CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
|
|
["CHAT_MSG_COMBAT_PET_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
|
|
["CHAT_MSG_SPELL_SELF_DAMAGE"] = combatlog_strings["Spell Damage (self vs. self/other)"],
|
|
["CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE"] = combatlog_strings["Spell Damage (other vs. self)"],
|
|
["CHAT_MSG_SPELL_PARTY_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
|
|
["CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
|
|
["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
|
|
["CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
|
|
["CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
|
|
["CHAT_MSG_SPELL_PET_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
|
|
["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] = combatlog_strings["Shield Damage (self vs. other)"],
|
|
["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] = combatlog_strings["Shield Damage (other vs. self/other)"],
|
|
["CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. other)"],
|
|
["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. other)"],
|
|
["CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. other)"],
|
|
["CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. other)"],
|
|
["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. self)"],
|
|
|
|
-- Heal
|
|
["CHAT_MSG_SPELL_SELF_BUFF"] = combatlog_strings["Heal (self vs. self/other)"],
|
|
["CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF"] = combatlog_strings["Heal (other vs. self/other)"],
|
|
["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] = combatlog_strings["Heal (other vs. self/other)"],
|
|
["CHAT_MSG_SPELL_PARTY_BUFF"] = combatlog_strings["Heal (other vs. self/other)"],
|
|
["CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS"] = combatlog_strings["Periodic Heal (self/other vs. other)"],
|
|
["CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS"] = combatlog_strings["Periodic Heal (self/other vs. other)"],
|
|
["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"] = combatlog_strings["Periodic Heal (self/other vs. other)"],
|
|
["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"] = combatlog_strings["Periodic Heal (other vs. self/other)"]
|
|
}
|
|
|
|
-- list of all possible patterns including the logic on how to parse them
|
|
local combatlog_parser = {
|
|
[SPELLLOGSCHOOLSELFSELF] = function(d, attack, value, school)
|
|
-- Your %s hits you for %d %s damage.
|
|
return d.source, attack, d.target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGCRITSCHOOLSELFSELF] = function(d, attack, value, school)
|
|
-- Your %s crits you for %d %s damage.
|
|
return d.source, attack, d.target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGSELFSELF] = function(d, attack, value)
|
|
-- Your %s hits you for %d.
|
|
return d.source, attack, d.target, value, d.school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGCRITSELFSELF] = function(d, attack, value)
|
|
-- Your %s crits you for %d.
|
|
return d.source, attack, d.target, value, d.school, "damage"
|
|
end,
|
|
|
|
[PERIODICAURADAMAGESELFSELF] = function(d, value, school, attack)
|
|
-- You suffer %d %s damage from your %s.
|
|
return d.source, attack, d.target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGSCHOOLSELFOTHER] = function(d, attack, target, value, school)
|
|
-- Your %s hits %s for %d %s damage.
|
|
return d.source, attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGCRITSCHOOLSELFOTHER] = function(d, attack, target, value, school)
|
|
-- Your %s crits %s for %d %s damage.
|
|
return d.source, attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGSELFOTHER] = function(d, attack, target, value)
|
|
-- Your %s hits %s for %d.
|
|
return d.source, attack, target, value, d.school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGCRITSELFOTHER] = function(d, attack, target, value)
|
|
-- Your %s crits %s for %d.
|
|
return d.source, attack, target, value, d.school, "damage"
|
|
end,
|
|
|
|
[PERIODICAURADAMAGESELFOTHER] = function(d, target, value, school, attack)
|
|
-- %s suffers %d %s damage from your %s.
|
|
return d.source, attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[COMBATHITSELFOTHER] = function(d, target, value)
|
|
-- You hit %s for %d.
|
|
return d.source, d.attack, target, value, d.school, "damage"
|
|
end,
|
|
|
|
[COMBATHITCRITSELFOTHER] = function(d, target, value)
|
|
-- You crit %s for %d.
|
|
return d.source, d.attack, target, value, d.school, "damage"
|
|
end,
|
|
|
|
[COMBATHITSCHOOLSELFOTHER] = function(d, target, value, school)
|
|
-- You hit %s for %d %s damage.
|
|
return d.source, d.attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[COMBATHITCRITSCHOOLSELFOTHER] = function(d, target, value, school)
|
|
-- You crit %s for %d %s damage.
|
|
return d.source, d.attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[DAMAGESHIELDSELFOTHER] = function(d, value, school, target)
|
|
-- You reflect %d %s damage to %s.
|
|
return d.source, "Reflect ("..school..")", target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGSCHOOLOTHERSELF] = function(d, source, attack, value, school)
|
|
-- %s's %s hits you for %d %s damage.
|
|
return source, attack, d.target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGCRITSCHOOLOTHERSELF] = function(d, source, attack, value, school)
|
|
-- %s's %s crits you for %d %s damage.
|
|
return source, attack, d.target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGOTHERSELF] = function(d, source, attack, value)
|
|
-- %s's %s hits you for %d.
|
|
return source, attack, d.target, value, d.school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGCRITOTHERSELF] = function(d, source, attack, value)
|
|
-- %s's %s crits you for %d.
|
|
return source, attack, d.target, value, d.school, "damage"
|
|
end,
|
|
|
|
[PERIODICAURADAMAGEOTHERSELF] = function(d, value, school, source, attack)
|
|
-- You suffer %d %s damage from %s's %s.
|
|
return source, attack, d.target, value, school, "damage"
|
|
end,
|
|
|
|
[COMBATHITOTHERSELF] = function(d, source, value)
|
|
-- %s hits you for %d.
|
|
return source, d.attack, d.target, value, d.school, "damage"
|
|
end,
|
|
|
|
[COMBATHITCRITOTHERSELF] = function(d, source, value)
|
|
-- %s crits you for %d.
|
|
return source, d.attack, d.target, value, d.school, "damage"
|
|
end,
|
|
|
|
[COMBATHITSCHOOLOTHERSELF] = function(d, source, value, school)
|
|
-- %s hits you for %d %s damage.
|
|
return source, d.attack, d.target, value, school, "damage"
|
|
end,
|
|
|
|
[COMBATHITCRITSCHOOLOTHERSELF] = function(d, source, value, school)
|
|
-- %s crits you for %d %s damage.
|
|
return source, d.attack, d.target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGSCHOOLOTHEROTHER] = function(d, source, attack, target, value, school)
|
|
-- %s's %s hits %s for %d %s damage.
|
|
return source, attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGCRITSCHOOLOTHEROTHER] = function(d, source, attack, target, value, school)
|
|
-- %s's %s crits %s for %d %s damage.
|
|
return source, attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGOTHEROTHER] = function(d, source, attack, target, value)
|
|
-- %s's %s hits %s for %d.
|
|
return source, attack, target, value, d.school, "damage"
|
|
end,
|
|
|
|
[SPELLLOGCRITOTHEROTHER] = function(d, source, attack, target, value, school)
|
|
-- %s's %s crits %s for %d.
|
|
return source, attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[PERIODICAURADAMAGEOTHEROTHER] = function(d, target, value, school, source, attack)
|
|
-- %s suffers %d %s damage from %s's %s.
|
|
return source, attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[COMBATHITOTHEROTHER] = function(d, source, target, value)
|
|
-- %s hits %s for %d.
|
|
return source, d.attack, target, value, d.school, "damage"
|
|
end,
|
|
|
|
[COMBATHITCRITOTHEROTHER] = function(d, source, target, value)
|
|
-- %s crits %s for %d.
|
|
return source, d.attack, target, value, d.school, "damage"
|
|
end,
|
|
|
|
[COMBATHITSCHOOLOTHEROTHER] = function(d, source, target, value, school)
|
|
-- %s hits %s for %d %s damage.
|
|
return source, d.attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[COMBATHITCRITSCHOOLOTHEROTHER] = function(d, source, target, value, school)
|
|
-- %s crits %s for %d %s damage.
|
|
return source, d.attack, target, value, school, "damage"
|
|
end,
|
|
|
|
[DAMAGESHIELDOTHERSELF] = function(d, source, value, school)
|
|
-- %s reflects %d %s damage to you.
|
|
return source, "Reflect ("..school..")", d.target, value, school, "damage"
|
|
end,
|
|
|
|
[DAMAGESHIELDOTHEROTHER] = function(d, source, value, school, target)
|
|
-- %s reflects %d %s damage to %s.
|
|
return source, "Reflect ("..school..")", target, value, school, "damage"
|
|
end,
|
|
|
|
[HEALEDCRITOTHERSELF] = function(d, source, spell, value)
|
|
-- %s's %s critically heals you for %d.
|
|
return source, spell, d.target, value, d.school, "heal"
|
|
end,
|
|
|
|
[HEALEDOTHERSELF] = function(d, source, spell, value)
|
|
-- %s's %s heals you for %d.
|
|
return source, spell, d.target, value, d.school, "heal"
|
|
end,
|
|
|
|
[PERIODICAURAHEALOTHERSELF] = function(d, value, source, spell)
|
|
-- You gain %d health from %s's %s.
|
|
return source, spell, d.target, value, d.school, "heal"
|
|
end,
|
|
|
|
[HEALEDCRITSELFSELF] = function(d, spell, value)
|
|
-- Your %s critically heals you for %d.
|
|
return d.source, spell, d.target, value, d.school, "heal"
|
|
end,
|
|
|
|
[HEALEDSELFSELF] = function(d, spell, value)
|
|
-- Your %s heals you for %d.
|
|
return d.source, spell, d.target, value, d.school, "heal"
|
|
end,
|
|
|
|
[PERIODICAURAHEALSELFSELF] = function(d, value, spell)
|
|
-- You gain %d health from %s.
|
|
return d.source, spell, d.target, value, d.school, "heal"
|
|
end,
|
|
|
|
[HEALEDCRITSELFOTHER] = function(d, spell, target, value)
|
|
-- Your %s critically heals %s for %d.
|
|
return d.source, spell, target, value, d.school, "heal"
|
|
end,
|
|
|
|
[HEALEDSELFOTHER] = function(d, spell, target, value)
|
|
-- Your %s heals %s for %d.
|
|
return d.source, spell, target, value, d.school, "heal"
|
|
end,
|
|
|
|
[PERIODICAURAHEALSELFOTHER] = function(d, target, value, spell)
|
|
-- %s gains %d health from your %s.
|
|
return d.source, spell, target, value, d.school, "heal"
|
|
end,
|
|
|
|
[HEALEDCRITOTHEROTHER] = function(d, source, spell, target, value)
|
|
-- %s's %s critically heals %s for %d.
|
|
return source, spell, target, value, d.school, "heal"
|
|
end,
|
|
|
|
[HEALEDOTHEROTHER] = function(d, source, spell, target, value)
|
|
-- %s's %s heals %s for %d.
|
|
return source, spell, target, value, d.school, "heal"
|
|
end,
|
|
|
|
[PERIODICAURAHEALOTHEROTHER] = function(d, target, value, source, spell)
|
|
-- %s gains %d health from %s's %s.
|
|
return source, spell, target, value, d.school, "heal"
|
|
end,
|
|
}
|
|
|
|
|
|
-- preload all combat log patterns
|
|
for pattern in pairs(combatlog_parser) do
|
|
sanitize(pattern)
|
|
end
|
|
|
|
-- cache default table
|
|
local defaults = { }
|
|
|
|
-- initialize absorb and resist pattern
|
|
local absorb = sanitize(ABSORB_TRAILER)
|
|
local resist = sanitize(RESIST_TRAILER)
|
|
|
|
-- scope all required variables
|
|
local _, num, pattern, result, a1, a2, a3, a4, a5
|
|
|
|
-- use same strings each time
|
|
local empty, physical, autohit = "", "physical", "Auto Hit"
|
|
local player = UnitName("player")
|
|
|
|
-- call all datasources on each event
|
|
local function OnEvent()
|
|
if not arg1 then return end
|
|
|
|
-- remove absorb and resist suffixes
|
|
arg1 = string.gsub(arg1, absorb, empty)
|
|
arg1 = string.gsub(arg1, resist, empty)
|
|
|
|
-- write default values
|
|
defaults.source = player
|
|
defaults.target = player
|
|
defaults.school = physical
|
|
defaults.attack = autohit
|
|
defaults.spell = UNKNOWN
|
|
defaults.value = 0
|
|
|
|
-- iterate over all patterns assigned to the current event
|
|
for _, pattern in pairs(combatlog_events[event]) do
|
|
result, num, a1, a2, a3, a4, a5 = cfind(arg1, pattern)
|
|
|
|
if result then
|
|
return parser:AddData(combatlog_parser[pattern](defaults, a1, a2, a3, a4, a5))
|
|
end
|
|
end
|
|
end
|
|
|
|
-- the chat combat log works on every client and is the fallback source
|
|
parser:RegisterSource("combatlog", {
|
|
available = function() return true end,
|
|
enable = function()
|
|
for event in pairs(combatlog_events) do
|
|
parser:RegisterEvent(event)
|
|
end
|
|
parser:SetScript("OnEvent", OnEvent)
|
|
end,
|
|
})
|