Skip to content

[Feature]: Midnight (retail 12.0+) CLEU removal — migrate combat detection to UNIT_* events with capability gating #28

Description

@Xerrion

Problem

Retail Midnight (interface 120000+, pre-patch 2026-01-28, launch 2026-03-02) has removed COMBAT_LOG_EVENT_UNFILTERED from the addon-accessible API surface. CombatLogGetCurrentEventInfo() now returns "secret values" that addons cannot read.

The restriction applies during boss encounters and Mythic+ runs specifically (per Icy Veins 2026-05-01 reporting on Blizzard's relaxations: "the restrictions will only apply during a boss encounter or Mythic+ run"). Open-world combat is unaffected by the restriction.

A new event COMBAT_LOG_EVENT_INTERNAL_UNFILTERED exists for engine use but is not the addon-facing replacement.

Consequence for DragonShout

PR #26 eliminates the ADDON_ACTION_FORBIDDEN taint error reported in #22 — but on retail Midnight, the underlying combat detection still does not function in raids/M+ because COMBAT_LOG_EVENT_UNFILTERED does not fire (or returns unreadable values) there. Classic flavors (MoP Classic 5.5.3, TBC Anniversary 2.5.5) are unaffected and continue to use CLEU normally.

Affected listeners:

  • Listeners/CombatLogListener.lua
  • Listeners/InterruptListener.lua
  • Listeners/AuraListener.lua
  • Listeners/DispelListener.lua

Primary-source citations

Cross-addon impact evidence

Proposed Solution

Migrate retail-Midnight combat detection to UNIT_* events plus the new namespaced APIs (C_UnitAuras, C_Spell), with capability gating so Classic flavors continue to use the existing CLEU path. Exactly one listener path fires per flavor.

Capability detection

Add a ns.capabilities table populated in Core/Init.lua during OnEnable:

local isMidnight = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE
    and select(4, GetBuildInfo()) >= 120000
ns.capabilities = {
    combatLog = not isMidnight, -- true on Classic flavors and pre-Midnight retail
}

Verify the exact build-number cutoff against Blizzard sources during implementation (do not hardcode against today's snapshot; cross-reference https://warcraft.wiki.gg/wiki/Public_client_builds).

New listener: Listeners/UnitEventListener.lua

Referenced as planned-but-missing in DragonShout/AGENTS.md "Gotcha #6". Registers on a private unnamed CreateFrame("Frame") (to avoid the Ace3 shared-bus taint issue tracked in #27). Listens for:

  • UNIT_SPELLCAST_INTERRUPT — replaces SPELL_INTERRUPT in InterruptListener
  • UNIT_AURA — replaces SPELL_AURA_APPLIED in AuraListener (consume via C_UnitAuras.GetAuraDataByIndex / GetAuraDataBySlot)
  • UNIT_SPELLCAST_SUCCEEDED — for dispels, with cast-target tracking

Gating

  • CombatLogListener.Initialize gates on ns.capabilities.combatLog.
  • UnitEventListener.Initialize gates on not ns.capabilities.combatLog.
  • Exactly one fires per flavor.

Public dispatch API stays unchanged

ns.InterruptListener.OnInterrupt(...), ns.AuraListener.OnAuraApplied(...), ns.DispelListener.OnDispel(...) keep their existing signatures — both source paths feed the same downstream handlers.

Adapter layer

UNIT_* event payloads differ from CLEU payloads. The UnitEventListener dispatch needs a small adapter to normalize source/dest GUID/name/flags into the same shape the existing OnX handlers expect. Document any payload fields that are no longer available on Midnight (e.g. some flag bits) so downstream handlers can gracefully degrade.

TOC

No structural change — all files load on every flavor; runtime guards select the path. Add Listeners/UnitEventListener.lua to the Listeners section of DragonShout.toc.

Alternatives Considered

  • Drop retail support entirely. Rejected — retail is the largest user base; DragonShout's TOC explicitly declares ## Interface: 120005.
  • Use COMBAT_LOG_EVENT_INTERNAL_UNFILTERED. Rejected — this is engine-internal, not the addon-facing replacement, and may be removed or restricted at any time.
  • Wait for Blizzard to relax further. Rejected — Icy Veins reports Blizzard has already relaxed (encounter-only restriction) and that is the final state per current information. Open-world functionality already works under current rules; the migration is specifically for raid/M+ functionality.
  • Add a pcall around addon:RegisterEvent and silently degrade. Rejected — masks the failure without restoring the feature.

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-CoreAddon lifecycle, slash commands, minimap iconA-ListenersCombat log listeners (interrupt, CC/aura, dispel)C-FeatureNew feature or enhancementD-ComplexMultiple files or systems involvedD-ExpertDeep WoW API knowledge or tricky edge casesP-MoP-ClassicMists of Pandaria ClassicP-RetailRetail-specific (11.x / 12.x)P-TBC-AnniversaryTBC Anniversary ClassicS-Needs-TriageNew issue awaiting review

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions