promotional bannermobile promotional banner

Cerebro

Modern EPGP & Loot Distribution with native RCLootCouncil & Mythic+ integration.

File Details

v0.10.33

  • R
  • Mar 21, 2026
  • 5.79 MB
  • 141
  • 12.0.1+1
  • Retail

File Name

Cerebro-v0.10.33.zip

Supported Versions

  • 12.0.1
  • 11.2.7

Cerebro

v0.10.33 (2026-03-21)

Full Changelog

  • chore: Bump version to 0.10.33
    Fix RCLC import pipeline (date filter, timestamps, dedup), add dry-run simulation command; hide voided transactions in History tab; targeted sync PUSH to divergent peer only; scope Sync Health display to active online peers
  • fix(ui): use consistent name format for self-skip in Addon Compliance
    Use GetFullPlayerName(UnitName("player")) instead of GetPlayerFullName()
    for the myName self-skip guard. This matches the same normalizer used for
    guild roster names (GetFullPlayerName(gName)), preventing self from being
    double-counted due to name format mismatch.
  • fix(ui): unify Addon Compliance with GetAddonState, remove dead code
    Replaced the entire manual addonStatus lookup + age + version comparison
    in the Addon Compliance tooltip section with v2:GetAddonState(full) — the
    same function that powers green/yellow/gray name colors in the player list.
    Removed ~30 lines of dead code: v2INACTIVE, maxVer, v2modRef, addonStatus
    variable — all now handled internally by GetAddonState. Self is counted
    unconditionally before the loop; the loop uses full ~= myName guard.
  • fix(ui): always count self in Addon Compliance synced count
    Self was being missed when GetPlayerFullName() and GetFullPlayerName(gName)
    produced slightly different name strings, causing full == myName to fail.
    Fixed by counting self unconditionally before the guild roster loop, and
    skipping self inside the loop via full ~= myName guard.
  • fix(ui): normalize peerHashes short name to full Name-Realm for GetAddonState
    AceComm passes sender as short name for same-realm peers, so peerHashes
    is keyed by short name (e.g. "Bearlybleeds") while addonStatus uses full
    Name-Realm format ("Bearlybleeds-Stormrage"). GetAddonState was always
    returning "unknown" for same-realm peers, causing count to be 1/1.
    Fix: normalize with GetFullPlayerName() before GetAddonState() in both
    ComputeSyncHealth and ShowSyncHealthTooltip.
  • fix(ui): tighten active-peer filter to synced/outdated only
    Previously included "inactive" peers (seen before, now offline) in the
    Sync % and tooltip peer counts. Changed condition from != "unknown" to
    == "synced" or == "outdated" so only players with an actively running
    addon are counted as live peers.
  • fix(ui): fix active-peer name key mismatch in sync health display
    peerHashes keys didn't match addonStatus keys, causing all peers to be
    excluded (showing 1/1 instead of 3/3). Replaced addonStatus[name]
    lookup with v2:GetAddonState(name) ~= "unknown" in both ComputeSyncHealth
    and ShowSyncHealthTooltip — same proven logic used by Addon Compliance.
  • fix(ui): scope Sync % and tooltip top rows to active peers only
    ComputeSyncHealth and ShowSyncHealthTooltip now filter peerHashes to
    peers seen within INACTIVE_THRESHOLD (90s). Offline/unknown peers no
    longer deflate the Sync % label or the top 3 tooltip rows (Sync Health,
    Roster Hash, Config Hash). Addon Compliance section is unchanged and
    still shows all guild members.
  • fix(sync): targeted WHISPER push on raider mismatch instead of GUILD broadcast
    When an officer detects a mismatch from a non-officer (raider/stale alt),
    send a targeted WHISPER to only that peer instead of broadcasting to
    RAID/GUILD. This prevents disrupting already-synced officers who would
    temporarily drop from synced state while re-processing the broadcast.
    • Reuses existing _lastSnapshotTo per-sender cooldown (same as officer path)
    • Removes _lastRaidBroadcastAt scalar (no longer needed for this path)
    • Net result: stale raider convergence is now invisible to synced peers
  • fix(ui): hide voided transactions in History tab; silence ghost stub debug spam
    • MainFrame/UISandbox History tabs now skip voided transactions
      (previously showed duplicates after RCLC import void+replace cycle)
    • GetFilteredPlayersForSync: remove per-heartbeat debug log for ghost
      stub skipping (Vrock-Eitrigg spam); expected behavior, not worth logging
  • fix(rclc-import): Fix import pipeline and add dry-run simulation
    • Add ParseDateArg (MM-DD-YYYY → YYYY/MM/DD RCLC format)
    • Remove duplicate ParseDateArg at EOF that returned Unix timestamp
    • Fix date scope filter to compare RCLC date strings (not servertime)
    • Add full Unix timestamp to NormalizeEntry from date+time fields
    • Fix AddTransaction to honor overrideTimestamp from options
    • Fix VoidTransactions to convert sinceDate string to Unix for comparison
    • Fix audit log bug (date() called with string instead of number)
    • Add SimulateImport dry-run (read-only, per-player GP report)
    • Register /cb rclc dryrun MM-DD-YYYY command
    • Bump version 0.10.32
  • fix(sync): fix persistent roster/selection hash divergence between officers
    Two bugs caused officers to never fully converge after PR37:
    Bug 1 — MergeSelectionData timestamp self-escalation (CommunicationV2.lua):
    When incoming selection was accepted, sf:SetSelection() internally called
    SaveSelection() which overwrote customEP.lastUpdate with time(). This ratcheted
    the local timestamp forward on every successful merge, making the local client
    perpetually "newer" than all peers. All future selection merges from those peers
    were REJECTED (theirs < mine forever), producing the continuous REJECTED spam seen
    in logs. Fix: restore incoming.lastUpdate after SetSelection() clobbers it.
    Bug 2 — RepairDatabase lastUpdate bump on login (Database.lua):
    The coreAdmittedAt backfill (data.coreAdmittedAt = 1) also bumped
    data.lastUpdate = time(). RepairDatabase runs on every login at different
    wall-clock seconds per officer, producing different lastUpdate values for
    identical EP/GP/status records. Since lastUpdate is included in ComputeRosterHash(),
    officers with identical data got different roster hashes → endless FETCH/PUSH loops.
    Fix: remove the lastUpdate bump — this is a schema migration, not a data mutation.
    Every officer independently applies this migration on login; LWW propagation
    is unnecessary and harmful."