promotional bannermobile promotional banner

VibeCheckLoot

Unlisted
VibeCheck is a full-featured EPGP loot management and attendance tracking addon built for World of Warcraft: The Burning Crusade Classic Anniversary

File Details

v1.2.0-bcc

  • R
  • May 5, 2026
  • 167.79 KB
  • 21
  • 2.5.5
  • Classic TBC

File Name

VCLoot-v1.2.0-bcc.zip

Supported Versions

  • 2.5.5

# VibeCheck Changelog

## 1.2.0 — May 5, 2026

### Security

**Sync.lua — sender-authority gate on every mutating message**
- `DELTA`, `BATCH_EP`, `RAID`, `SETTINGS`, `HIST_DEL`, `ROLL_START`, `ROLL_END`, and `FULL` (including the season-bump hard-wipe path) are now rejected unless the sender holds Vibe Master / Officer / Officer Alt / Loot Master rank, OR is the in-game Master Looter, OR (for leader-or-officer messages) is the current group leader. Previously any guild member could broadcast a forged `DELTA` to award arbitrary EP/GP, push a forged `SETTINGS` to corrupt every roster's GP formula, or wipe every receiver's database via a forged season bump. Guild ranks are looked up via a 30-second cached `GetGuildRosterInfo` table.
- `PROFILE` messages now require the in-payload player name to match the sender. Without this, anyone could overwrite anyone else's role, gear snapshot, and wishlist on every client.
- Numeric `SETTINGS` values are clamped to per-key sane bounds (`gpFinalMult` 0.0001–1000, `decayPercent` 0–100, etc.) so an out-of-range push (or `inf`/NaN) cannot land. `BATCH_EP` and `DECAY DELTA` amounts are clamped to sane upper bounds (≤100 000 EP per kill; 0–100 % decay).
- Only officers reply to `REQ FULL`; non-officer replies would be rejected on receive anyway, and skipping the send saves bandwidth and reduces flood risk.

### Bug Fixes

**Sync.lua**
- Fixed lifetime EP/GP double-count on offline-divergence reconciliation. The old code adopted the sender's `lifeEP` via `max(local, incoming)` and then *also* added local-unique entries' amounts on top, compounding lifetime totals every time a FULL sync triggered the replay path. `applyHistoryEntries` now takes a `replayMode` flag that skips the lifetime bump.
- Fixed `mergeHistory` truncating local history to 1 000 rows when the local DB cap is 2 000. Receiving a FULL no longer silently drops rows the local SavedVariables would otherwise keep — both ends now reference `ns.C.MAX_HISTORY`.
- Fixed `histKey` collisions when two officers awarded the same EP amount to the same player in the same wall-clock second. The dedup key now includes `by`. A `legacyHistKey` fallback keeps pre-1.2 tombstones working during the transition window.
- Fixed `BATCH_EP` re-application on redelivery. Receivers now build a `seenKeys` set from current history and skip rows that already exist, so a redelivered or twice-fired BATCH_EP does not double-credit attendees.
- Fixed `DELTA` re-application on redelivery: receivers now check the canonical histKey against existing history before applying.
- Fixed chunked-transfer expiry being measured from the *first* chunk's wall-clock arrival rather than last activity. A FULL exceeding ~600 chunks (~140 KB) was silently discarded mid-stream. Expiry is now last-activity-based and the window is raised from 30 s to 60 s.
- Fixed self-echo guard's short-name comparison dropping legitimate messages from a same-realm group member who shares a first name with the local player. Comparison now uses normalized full names.
- Fixed `CHUNK_SIZE = 230` cutting close to the 255-byte addon-message cap (worst-case framed header for `BATCH_EP` could push the total over). Reduced to 215 with explicit header-size accounting documented inline.
- Fixed `hasLocalUnique` rev-bump being set against the *unfiltered* local-unique list. Tombstoned entries that had already been deleted elsewhere were counted as new data we needed to advertise, causing peers to needlessly request a FULL from us. Now reflects the post-tombstone-filter count.
- Fixed unbounded growth of `presence` / `inbox` / `reqLastSent` when `syncEnabled = false` (Heartbeat never runs and never prunes). A throttled `maybePrune` runs from `OnMessage` every 60 s.

**Sync.lua / DB.lua / UI.lua — history deletion now reverses EP/GP**
- Centralized `DB:DeleteHistoryEntry(idx)` reverses the entry's EP/GP impact on the roster, drops the row, tombstones the canonical histKey, and bumps `dbRev` in one call. Both the UI right-click delete and the sync `HIST_DEL` handler use it. Previously the row was removed from the visible log but the points it awarded stayed on the player. `applyTombstones` (FULL receipt) now also reverses EP/GP for tombstoned rows.

**Slash.lua — `/vcl sync` no longer floods the guild**
- `/vcl sync` now uses the targeted-best-peer flow (whisper exactly one peer for a FULL response) instead of broadcasting `REQ FULL` to GUILD where every online addon user simultaneously responds. If no peers are known (cold start) it fires a heartbeat, waits 3 s for replies, then falls back. `/vcl sync force` skips the wait and broadcasts immediately.

**Decay.lua**
- Fixed `decayBaseGP = false` (the "protect base GP" mode) silently doing nothing because it referenced `s.baseGP`, but the actual setting key is `s.gpBase`. The floor protection has never engaged since the GP-formula migration; it works correctly now.

**Attendance.lua**
- Wipe-EP awards now use one `BATCH_EP` message instead of N per-player `DELTA` messages, matching the boss-kill flow. This both cuts traffic and lets non-officer raid leaders broadcast wipe credit (DELTA is officer-only post-1.2; BATCH_EP is leader-or-officer).

### Version

- Bumped from **1.1.0** to **1.2.0** — sync hardening + security gates.

---

## 1.0.0 — April 29, 2026

### Bug Fixes

**Loot.lua / Core.lua**
- Fixed double `HandleModifiedItemClick` hook. When Bag Roll modifier was set to Alt (the default), both the Core.lua hook (`Loot:OnAltClick`) and the UI.lua bag-roll hook fired on the same alt-click, opening the roll prompt twice. `OnAltClick` now yields when the bag roll modifier already covers that gesture.

**UI.lua**
- Fixed free roll auto-detection using `GetNumGroupMembers()`. A 25-man raid with fewer than 20 people online would falsely trigger the 10-man free roll default. Detection now uses `maxPlayers` from `GetInstanceInfo()`, which returns the instance's hard cap (10 for Kara/ZA, 25 for 25-man content), and is therefore always accurate regardless of current attendance.
- Fixed free roll checkbox state not being passed correctly to `StartRoll` when unchecked in a 10-man instance. The checkbox visual updated correctly but the state read by the start button could be stale. State is now snapshotted into a local before the prompt frame is hidden.
- Fixed multiple Unicode characters rendering as blank squares in-game: em-dash (`—`) and middle-dot (`·`) in `SetText`, `AddLine`, and `ns.Print` calls across UI.lua and Backup.lua replaced with ASCII equivalents.
- Fixed the wish list "Done" button displaying `←` and `—` as blank boxes; replaced with `<<` and `-`.

**WishListData.lua**
- Fixed item IDs and boss assignments for Zul'Aman, Hyjal Summit, Black Temple, and Sunwell Plateau. Nearly all entries across these four raids had incorrect item IDs, wrong item names, or were assigned to the wrong boss. All four raids have been rewritten with correct Wowhead-verified data including tier token assignments (Azgalor = T6 gloves, Archimonde = T6 helms, Mother Shahraz = T6 shoulders, Illidari Council = T6 legs, Illidan = T6 chest, Kalecgos = SWP bracers, Brutallus = SWP belts, Felmyst = SWP boots, Eredar Twins = SWP necks, M'uru = SWP rings, Kil'jaeden = SWP chest).

---

### New Features

**Sync.lua — Tombstone System**
- History deletions are now durable across syncs. When an officer deletes a history entry, its key is recorded in a tombstone set (`db.deletedHistKeys`) with a timestamp. Full sync payloads include a `---TOMBSTONES---` section; receiving clients apply incoming tombstones after merging history, permanently removing any re-introduced entries. Tombstones expire after 90 days and are pruned on send and receive to prevent unbounded growth.

**UI.lua — Bag Roll Modifier**
- Added a configurable modifier key for clicking bag items to open the roll session prompt. Configured in Settings → Loot Distribution → Bag Roll. Options: None (disabled), Alt-click, Ctrl-click, or Alt+Ctrl-click. Replaces the previous hardcoded alt-click behavior with an explicit, user-controlled setting.

**UI.lua — Addon Hotkey Relocated**
- The keyboard shortcut for opening/closing the VibeCheck window has been moved from the Loot Distribution tab to the Sync & Data tab, which is a more appropriate home for a UI preference that is not related to loot settings.

**UI.lua — Free Roll Auto-Check for 10-Man**
- The Free Roll checkbox in the roll-start prompt is now automatically pre-checked when you are inside a 10-man instance (Karazhan or Zul'Aman), defaulting to the no-EPGP roll mode appropriate for those raids. The checkbox remains interactive — officers can uncheck it to run a normal EPGP roll if needed.

---

### Version

- Bumped from 0.9.5 to **1.0.0** — first full public release.

---

## 0.6.0

### Bug Fixes

**Decay.lua**
- Fixed incorrect default decay day-of-week. The fallback was `2` (Monday) but the setting default in Constants is `3` (Tuesday). Decay now fires on the correct night for guilds who never changed this setting.
- Fixed incorrect default decay hour. The fallback was `6` (6 AM) but the setting default is `0` (midnight). Both defaults now match Constants.DEFAULTS.

**Core.lua / Loot.lua**
- Fixed encapsulation bug where `Core.lua` was directly writing `ns.Loot.tradeBothAccepted = false` after `TRADE_CLOSED`. The flag is now read and reset entirely inside `Loot:OnTradeClosed()`. Core just calls the method with no arguments.

**Attendance.lua**
- Fixed `benchEPMultiplier` not being bounds-checked. A value above 1.0 would award bench players more EP than raiders. The multiplier is now clamped to `[0, 1]` before use.

**Sync.lua**
- Fixed SYNCABLE_SETTINGS guard on the *receive* side. Previously, unknown keys from a newer client version could be written into settings. Settings received over sync are now validated against the explicit whitelist before being applied.

---

### New Features

**Sync — Alt Map Propagation**
- Full sync payloads now include an `---ALTS---` section. Alt links set by any officer will now propagate to all addon users on the next full sync. Incoming links are merged non-destructively (conflicts are skipped rather than overwritten).

**Sync — Last-Sync Status Indicator**
- The addon now tracks `Sync.lastSyncTime` and `Sync.lastSyncSender` whenever a full sync is applied.
- The Settings → Sync & Data sub-tab shows a live status line: "Last sync: 3m ago from Playername" or "Not yet synced this session."

**WishListData — Phase 3–5 Content**
- Added complete wish list item databases for all remaining TBC phases:
  - **Zul'Aman** (6 bosses: Nalorakk, Akil'zon, Jan'alai, Halazzi, Hex Lord Malacrass, Zul'jin)
  - **Hyjal Summit** (5 bosses: Rage Winterchill, Anetheron, Kaz'rogal, Azgalor, Archimonde) — includes all T6 token slots
  - **Black Temple** (9 bosses: Naj'entus through Illidan) — includes both Warglaives
  - **Sunwell Plateau** (6 bosses: Kalecgos through Kil'jaeden) — includes Thori'dal

**Constants — Zul'Aman Boss List**
- Added all 6 Zul'Aman NPC IDs to `BOSS_LIST` for completeness, consistent with the existing Karazhan entries. Kill detection is still filtered to 20+ man raids so no EP will auto-award from ZA — the entries are informational.

**Settings — CSV Export**
- The "Export CSV" button in Settings → Sync & Data now opens an in-game copy dialog with the full roster CSV (sorted alphabetically), instead of dumping each line to chat. Copy and paste directly into a spreadsheet.

---

### Removals (approved)

**Slash Commands**
- Removed `/vcl test roll` — seeded fake roll sessions for UI testing. No longer needed now that the roll window is stable.
- Removed `/vcl test raid` — injected fake Gruul + Magtheridon raids. Removed alongside the 140-line injection block in `Slash.lua`.
- Removed `/vcl export` — chat-line CSV dump. Replaced by the in-game copy dialog in the Settings tab.

**Loot.lua**
- Removed `StartTestRoll()`, `TEST_ITEMS`, and `FAKE_RAIDERS` (~90 lines of test scaffolding).

---

### Performance / Quality

**Sync — History Cap**
- `HISTORY_SYNC_MAX` raised from 200 to 500 entries in outbound FULL payloads.
- Local post-merge history cap raised from `HISTORY_SYNC_MAX * 2` (400) to a fixed 1000 entries, matching the UI's display limit.

---

## 0.5.0

- Standings tab: complete rewrite with role filter pills (All / Tank / Healer / Melee / Ranged), PR rank column, attendance color coding, and Shift+Click double-sort on any column.
- Log tab: Raids sub-tab with zone filter pills, duration column, and pulsing "In progress" row. History sub-tab with date-range filter (All / Today / Week / Month), clickable player name filter, and totals footer.
- Fixed inline search-bar clear button (X) misalignment in Standings.
- Fixed "0 PR" filter button labels — now "Show 0 PR" / "Hide 0 PR".
- Standings sort now defaults to PR descending. Shift+Click any column header to set a secondary sort key.
- Fixed Unicode characters rendering as blank squares in-game. All rendered strings now use ASCII-only substitutes.

## 0.4.x and earlier

See git history.