mirror of
https://codeberg.org/Duvelcorp/MetaHunt.git
synced 2026-09-27 01:56:04 +00:00
v1.4.1 event leak fixes, chronometer trap fix, profile memory, autostrip alloc fix
This commit is contained in:
@@ -40,10 +40,13 @@ function MTH_ChronometerHunterInstallData(engine)
|
||||
engine:AddTimer(engine.SPELL, BS["Wyvern Sting"], 12, 1, 0, 0, { gr = 2, cr = "MAROON", rc = true })
|
||||
engine:AddTimer(engine.SPELL, BS["Feed Pet"], 20, 0, 0, 0, { cr = "MAROON" })
|
||||
|
||||
engine:AddTimer(engine.EVENT, BS["Explosive Trap Effect"], 20, 1, 0, 1, { gr = 1, cr = "ORANGE", a = 1, xn = BS["Explosive Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Freezing Trap Effect"], 10, 1, 0, 1, { gr = 1, cr = "CYAN", a = 1, d = { rs = 5, tn = BS["Clever Traps"], tb = 0.15, tp = 1 }, xn = BS["Freezing Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Frost Trap Aura"], 30, 0, 0, 0, { gr = 1, cr = "CYAN", a = 1, d = { tn = BS["Clever Traps"], tb = 0.15, tp = 1 }, xn = BS["Frost Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Immolation Trap Effect"], 15, 1, 0, 1, { gr = 1, cr = "ORANGE", a = 1, xn = BS["Immolation Trap"] })
|
||||
-- Trap effects: no "a=1" here — primed by the SPELL timer's "ea" chain (cast hook sets timer.v
|
||||
-- and timer.t). Using "a=1" would trigger on any hunter's affliction message since
|
||||
-- CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS never embeds a caster name.
|
||||
engine:AddTimer(engine.EVENT, BS["Explosive Trap Effect"], 20, 1, 0, 1, { gr = 1, cr = "ORANGE", xn = BS["Explosive Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Freezing Trap Effect"], 10, 1, 0, 1, { gr = 1, cr = "CYAN", d = { rs = 5, tn = BS["Clever Traps"], tb = 0.15, tp = 1 }, xn = BS["Freezing Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Frost Trap Aura"], 30, 0, 0, 0, { gr = 1, cr = "CYAN", d = { tn = BS["Clever Traps"], tb = 0.15, tp = 1 }, xn = BS["Frost Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Immolation Trap Effect"], 15, 1, 0, 1, { gr = 1, cr = "ORANGE", xn = BS["Immolation Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Improved Concussive Shot"], 3, 1, 0, 0, { a = 1, cr = "BLUE", xn = BS["Concussive Shot"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Improved Wing Clip"], 5, 1, 0, 0, { a = 1, cr = "MAROON", xn = BS["Wing Clip"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Lock and Load"], 10, 0, 1, 1, { a = 1, cr = "MAROON", tx = "Interface\\Icons\\ability_hunter_lockandload" }) -- 10s (tooltip confirmed; expires on Aimed Shot cast)
|
||||
|
||||
@@ -580,14 +580,18 @@ function Chronometer:OnEnable()
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_AURA_GONE_SELF", function(event, info) self:SPELL_FADE(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_AURA_GONE_OTHER", function(event, info) self:SPELL_FADE(event, info) end)
|
||||
|
||||
-- Registered events:
|
||||
-- SELF_BUFFS / SELF_DAMAGE → our own procs & self-damage (source == ParserLib_SELF confirmed)
|
||||
-- CREATURE_DAMAGE → DOT ticks on creatures ("from your X" embeds source; filtered in SPELL_PERIODIC)
|
||||
-- CREATURE_BUFFS → debuff APPLICATION on creatures ("X is afflicted by Y"; no source embedded).
|
||||
-- Needed for non-ticking debuffs: Poisonous/Enchanted Ammunition, Piercing Shot.
|
||||
-- Foreign-bar risk is mitigated in SPELL_PERIODIC by requiring victim == target
|
||||
-- when source is nil and no confirmed cast record exists.
|
||||
-- FRIENDLYPLAYER_*, HOSTILEPLAYER_* are other players' events → intentionally NOT registered.
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
|
||||
local enableRoM = false
|
||||
for _, timer in pairs(self.timers[self.SPELL] or {}) do
|
||||
@@ -1274,11 +1278,20 @@ end
|
||||
function Chronometer:SPELL_PERIODIC(event, info)
|
||||
local aura, rank, unit, isgain
|
||||
|
||||
-- Ignore events not caused by the player (e.g. other players' DOTs/traps nearby)
|
||||
-- Primary filter: explicit non-self source → always ignore (other player's confirmed event)
|
||||
if info.source and info.source ~= ParserLib_SELF then return end
|
||||
|
||||
-- Secondary filter: creature/friendly periodic events do NOT embed a caster name,
|
||||
-- so info.source is nil even for other players' effects. Track whether this event
|
||||
-- was provably ours (SELF_BUFFS / SELF_DAMAGE events give source == ParserLib_SELF).
|
||||
local sourceIsConfirmedSelf = (info.source == ParserLib_SELF)
|
||||
|
||||
if info.type == "buff" then
|
||||
isgain = 1
|
||||
-- Buff gained by someone other than self with no source confirmation → another player's proc
|
||||
if not sourceIsConfirmedSelf and info.victim ~= nil and info.victim ~= ParserLib_SELF then
|
||||
return
|
||||
end
|
||||
elseif info.type == "debuff" then
|
||||
isgain = nil
|
||||
elseif not info.isDOT then
|
||||
@@ -1306,7 +1319,27 @@ function Chronometer:SPELL_PERIODIC(event, info)
|
||||
if timer.k.t then
|
||||
if not unit then unit = UnitName("player") end
|
||||
if timer.k.s then
|
||||
if timer.t and timer.t ~= unit then return end
|
||||
-- Selforselect: four-tier confirmation.
|
||||
-- 1. Confirmed cast record (timer.t set by CastSpell hook): require target match.
|
||||
-- 2. Confirmed self source (SELF_BUFFS / SELF_DAMAGE events, source == SELF): accept.
|
||||
-- 3. Cast-window confirmed (timer.v fresh, timer.t nil): untargeted spells like traps
|
||||
-- where the caster is known but the trigger victim cannot be predicted in advance.
|
||||
-- Accept unconditionally — the mob that walked into the trap may not be our target.
|
||||
-- 4. Source unconfirmed AND no cast record (CREATURE_BUFFS affliction messages never
|
||||
-- embed a caster name): fall back to target-check. This lets non-ticking debuffs
|
||||
-- (Poisonous Ammo, Enchanted Ammo, Piercing Shot…) show when applied to our current
|
||||
-- target, while blocking the same debuff on a mob we are NOT targeting (i.e. another
|
||||
-- player's debuff on a different dummy).
|
||||
if timer.t then
|
||||
if timer.t ~= unit then return end
|
||||
elseif sourceIsConfirmedSelf then
|
||||
-- source confirmed → accept unconditionally
|
||||
elseif timer.v and timer.v > GetTime() then
|
||||
-- cast-window confirmed, timer.t nil → untargeted cast (e.g. trap placed on ground)
|
||||
-- victim unknown at cast time; accept whatever mob triggered it
|
||||
elseif not UnitExists("target") or unit ~= UnitName("target") then
|
||||
return
|
||||
end
|
||||
else
|
||||
if not UnitExists("target") or unit ~= UnitName("target") then return end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local MTH_ChronometerModule = {
|
||||
name = "chronometer",
|
||||
enabled = true,
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
events = {},
|
||||
initialized = false,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user