DopingControl 0.7.0
This commit is contained in:
+406
@@ -0,0 +1,406 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to DopingControl. Versions are the ones actually
|
||||
released here — a new feature raises the middle number and resets the last
|
||||
one, the last number is for fixes without new features.
|
||||
|
||||
## v0.7.0
|
||||
|
||||
### New Addons tab: who in the raid runs BigWigs, Threat Meter, EPGP, SuperWoW, Rinse
|
||||
|
||||
A seventh tab checks the raid's addons without the other raiders needing
|
||||
DopingControl. Each column is detected only through what that addon sends or
|
||||
answers: BigWigs' version query, the TW Threatmeter "who" query, shootyepgp's
|
||||
version announcement and its SuperWoW reply, and UpsiRinse's version query.
|
||||
|
||||
* **Version in every cell.** Green with a check mark = the newest version in
|
||||
the raid (your own row counts); green with an exclamation mark = present but
|
||||
older (the tooltip names the newest); red = no reply after the query
|
||||
window. Versions compare numerically per segment, and only within the same
|
||||
BigWigs fork.
|
||||
* **Honest silence.** Red only after a query window passed; before any query a
|
||||
cell is grey "?". Not-in-guild (EPGP/SuperWoW) and non-dispeller classes
|
||||
(Rinse) are "n/a", not red. The red tooltip says what it really means: not
|
||||
installed, an old version, or a fork that does not answer.
|
||||
* **Check addons** button; opening the tab runs one automatic check, at most
|
||||
every 30 seconds, never in combat and never on joining a raid. A passive
|
||||
listener records versions that addons announce on their own, and forgets
|
||||
raiders who left.
|
||||
* Your own row is read from your own addon list instead of waiting for replies.
|
||||
* `/dc test` shows a deterministic mix of states on this tab.
|
||||
* This adds a new file (`scan/addons.lua`), so the game must be restarted
|
||||
once, not just reloaded.
|
||||
|
||||
### Equipment tab names the enchant, not just "enchanted"
|
||||
|
||||
Hovering an Equipment cell used to say only "Enchanted" or "Not
|
||||
enchanted". It now shows which permanent enchant the slot carries
|
||||
("Enchant: Crusader", "Enchant: Agility +15", ...). The names come from a
|
||||
table generated from the game client's own enchant data, so they match
|
||||
what the client shows, including server-custom enchants. An enchant that
|
||||
is not in the table shows as "enchant #<id>": it is still known to be
|
||||
enchanted, only the name is unknown, and it is never reported as missing.
|
||||
|
||||
### The addon does the pre-raid test-mode check itself
|
||||
|
||||
`/dc test` is persisted, so it survives a reload and a relog. A session
|
||||
that ended with the simulated raid on screen started the next one showing
|
||||
it again — and from then on the matrix graded a roster that does not
|
||||
exist. On screen the only marker was the source banner, so the failure
|
||||
mode was never an error, just a plausible wrong answer. That is the worst
|
||||
kind for a buff checker, and "remember to check before the raid" is not a
|
||||
routine anyone keeps.
|
||||
|
||||
Now the addon says it, at the two moments it matters:
|
||||
|
||||
* **Once per login or reload** — printed on world entry, not earlier;
|
||||
chat output before that point is silently dropped.
|
||||
* **When a group forms** — on the 0 → grouped edge only, so a raid
|
||||
filling up prints it once, not once per member.
|
||||
|
||||
Both lines name the mode that is actually on and the switch that leaves
|
||||
it (`/dc test` or `/dc demo`) — naming the wrong one would send you to a
|
||||
toggle that changes nothing.
|
||||
|
||||
### "readable" means one thing now — the footer and the tooltips caught up
|
||||
|
||||
v0.6.1 gave the coverage pill its channel nouns (`15/26 hit read`), but the
|
||||
footer strip on the Hit and Resistances tabs still said **AVERAGE
|
||||
(READABLE)**, the chat report still said "average, readable players", and
|
||||
the empty-slot tooltips said "unit readable" — all naming the gear/hit/
|
||||
resist read while the word elsewhere (the `Not readable` list, the
|
||||
`N unreadable` chips, the `N/N readable` group chip) means "this player
|
||||
could be read at all". Same word, two populations, on one screen.
|
||||
|
||||
Decided and pinned in a code comment (`core/model.lua`, `CoverageLabel`):
|
||||
**"readable" = the player could be read this scan (online, auras
|
||||
answered)** — and nothing else. Every channel-specific population is
|
||||
named by its channel: `gear read`, `hit read`, `resist read`.
|
||||
|
||||
* Footer on Hit / Resistances: **AVERAGE (HIT READ)** / **AVERAGE (RESIST
|
||||
READ)** — derived from the same function as the pill, so the two can
|
||||
no longer drift apart.
|
||||
* Chat report section headers: `Hit (average, hit-read players):` /
|
||||
`Resistances (average, resist-read players):`.
|
||||
* Empty-slot tooltips: `gear read, no trinket equipped …`, `gear read, no
|
||||
item equipped …`; the generic "slot empty" line takes the tab's noun
|
||||
(`readable` on the aura tabs, `gear read` on Equipment).
|
||||
* Coverage-pill tooltip on gear/hit/resist tabs now leads with the pill's
|
||||
own number and noun (`15 of 26 hit read`), then the row-readability
|
||||
line (`26 of 26 raid members readable (online, auras answered)`) —
|
||||
before, the pill said `15/26` and its tooltip `26 of 26`.
|
||||
* Two more spots missed the first pass: the gear-unreadable row's status
|
||||
chip and its row-spanning explanation (`ui/matrix.lua` `UnreadRowText`,
|
||||
`core/model.lua` `row.unreadNote`) said `items not readable` — right
|
||||
next to a group header that counts that same row as readable (only its
|
||||
EQUIPMENT channel came back empty). Both now say `gear not read`.
|
||||
|
||||
## v0.6.4
|
||||
|
||||
### Equipment expectation top-up now self-heals every refresh, not just once at ADDON_LOADED
|
||||
|
||||
Field report after v0.6.3 shipped (WAIST seeded `true` for every role):
|
||||
after deploying and reloading, the Equipment matrix still showed 16
|
||||
columns (no WAI) and the owner's own row read "(read failed)" / sum "--".
|
||||
|
||||
Offline reproduction against the real captured dump
|
||||
(`dc_raid_1788070493.txt`, the scan taken right after the reload) and the
|
||||
real live `db.expectations` shape
|
||||
(`WTF\...\SavedVariables\DopingControl.lua`, all 20 role/class lines —
|
||||
`NECK`/`R1`/`R2 = true`, `WAIST` absent everywhere) through the actual
|
||||
`DC_Gear.Assemble` -> `DC_Model.build` -> `DC_Matrix` pipeline found no
|
||||
Lua error anywhere — no nil dereference, nothing caught by a `pcall`.
|
||||
Both symptoms are real, and neither is what it first looked like:
|
||||
|
||||
* The "(read failed)"/"--" row is a correct, unrelated read: the dump's
|
||||
own `P`/`H`/`X` lines already carry `aurasRead=0`/
|
||||
`unreadableReason=read failed` before any render happens —
|
||||
`scan/aura.lua`'s "zero USABLE auras this scan => aurasRead=false" rule
|
||||
firing on a genuine zero-buff moment. Nothing to do with WAIST or
|
||||
equipment.
|
||||
* The missing WAIST column traces to `core/model.lua`'s `anyClassExpects`:
|
||||
it only falls back to the `DC.DEFAULT_EXPECT` seed for a (role, class)
|
||||
combo with NO saved line at all — an *existing* class line (any line
|
||||
materialized before the v0.6.3 seed change) is trusted as complete, key
|
||||
by key. `DC.EnsureExpectations`/`topUpLine` (`core/config.lua`) are
|
||||
themselves correct — proven by running them against the exact real
|
||||
saved shape above — but they only ran once, at `ADDON_LOADED`. A
|
||||
`db.expectations` line materialized before v0.6.3 shipped therefore
|
||||
stayed short the new key until a SECOND full reload happened to run
|
||||
`EnsureExpectations` again against the current seed.
|
||||
|
||||
Fix: `ui/matrix.lua`'s `MX.ExpectTable` — the one resolver both the header
|
||||
and `MX.Refresh` read the expectation table from — now defensively re-runs
|
||||
`DC.EnsureExpectations(d)` every time it resolves, i.e. on every
|
||||
scan/window redraw, not only once at boot. `topUpLine` only ever fills
|
||||
`nil` keys, so this is idempotent and side-effect-free on an
|
||||
already-current table; it self-heals a stale class line the moment the
|
||||
window redraws, without requiring a second reload.
|
||||
|
||||
New regression test `tools/luatests/test_expectations_topup.lua`: embeds
|
||||
the real captured `db.expectations` shape (all 20 role/class lines,
|
||||
verbatim) and a real gear/hit dump line, reproduces the exact
|
||||
16-column/no-WAI/`(read failed)` symptom through the unmodified
|
||||
`DC_Model.build`, then proves `MX.ExpectTable` self-heals it to 17 columns
|
||||
with WAIST at column 6.
|
||||
|
||||
## v0.6.3
|
||||
|
||||
### Waist is expected by default for every role
|
||||
|
||||
Owner decision, reversing the "confirmed, not a bug" call below: every role
|
||||
wears an enchantable belt, so WAIST now belongs with the other worn
|
||||
equipment slots (HEAD, CHST, WRST, ...) instead of the opt-in neck/ring
|
||||
treatment. `data/expectations.lua`'s seed now carries `WAIST = true` for
|
||||
all five roles. Existing SavedVariables pick up the flag automatically —
|
||||
`core/config.lua`'s `topUpLine` already adds any seed slot the saved line
|
||||
has never seen (`nil`) as `true` on load, the same mechanism that
|
||||
delivered the neck/ring columns to existing saves; no separate migration
|
||||
was needed. An explicit `WAIST = false` set for a role/class still hides
|
||||
the column, same opt-out behavior as any other slot.
|
||||
|
||||
### Confirmed: the waist column's off-by-default is intended, not a bug
|
||||
|
||||
A field report said the belt was worn but the Equipment tab still showed
|
||||
16 columns, no WAI, after the v0.6.2 waist-slot fix was deployed and the
|
||||
UI reloaded. Traced end to end (`core/model.lua` `tabSlots`/
|
||||
`anyClassExpects`, `ui/matrix.lua`'s `vm.slots` column build, the live
|
||||
SavedVariables `expectations` table): the gating is working exactly as
|
||||
v0.6.2 shipped and tested it — the waist enchant column is opt-in per
|
||||
role/class, the same treatment as neck/rings, and simply had not been
|
||||
enabled for any role/class yet (unlike neck/rings, which already carry
|
||||
`= true` in every class line of the reporting player's save from before
|
||||
this default existed). No code was hiding anything; the column appears
|
||||
the moment the checkbox is enabled in Options > Equipment.
|
||||
|
||||
Added a regression test (`tools/luatests/test_model.lua`, section 8d)
|
||||
that exercises the real production path — `core/model.lua`'s `M.build`
|
||||
through `tabSlots`/`anyClassExpects`, the same function `ui/matrix.lua`
|
||||
renders from — instead of the static `DC.SLOTS_EQUIPMENT` array the
|
||||
layout test uses. It pins both halves: WAIST absent from `vm.slots`
|
||||
under the default seed, and present + classifying correctly (HAS/
|
||||
MISSING/UNKNOWN) once a role/class expectation is switched on. This
|
||||
closes the gap that let the "is it really gated correctly" question go
|
||||
unanswered by the existing suite.
|
||||
|
||||
## v0.6.2
|
||||
|
||||
A fix release.
|
||||
|
||||
### The waist slot was never scanned
|
||||
|
||||
No equipment read — the raid dump, the Equipment tab, the Hit tab's
|
||||
belt contribution — ever covered the waist (inventory slot 6). The slot
|
||||
list that drives every `GetInventoryItemLink` read was borrowed from the
|
||||
Equipment tab's enchant-tracking column list, which had no waist column;
|
||||
that list never included the waist at all, so it was silently skipped in
|
||||
every read that reused it, not only display.
|
||||
|
||||
The waist turns out to be enchantable on this server (a custom "Belt
|
||||
Buckle" item line, the same kind of addition that already made the neck
|
||||
and both rings enchantable beyond stock behaviour), so it now gets its
|
||||
own Equipment-tab column — off by default, like the neck and ring
|
||||
columns, until enabled per role/class in the options grid.
|
||||
|
||||
## v0.6.1
|
||||
|
||||
A fix release. Everything here is something that was supposed to work
|
||||
already — most of it found by running the addon in a real 26-man raid and
|
||||
then checking what it had actually read.
|
||||
|
||||
### Resistances of other players are readable at last
|
||||
|
||||
The Resistances tab shipped in v0.6.0 and showed `?` for everyone but you.
|
||||
That was not a display bug: this client is never told other players'
|
||||
resistances. Both read paths return `0` for a raid member standing next to
|
||||
you, fully loaded — including their armour value, which is the giveaway
|
||||
that the field is simply not transmitted rather than genuinely zero.
|
||||
|
||||
The numbers are now **reconstructed from the equipped items' tooltips** —
|
||||
the same route the Hit tab already takes — and `Equip: +N All Resistances`
|
||||
counts on all five schools. On top of that comes the **racial bonus**,
|
||||
which is written in no item: Dwarf +10 Frost, Gnome +10 Arcane, Night Elf
|
||||
and Tauren +10 Nature, Undead +10 Shadow. Goblin and High Elf get nothing
|
||||
added, because no resistance racial for them could be confirmed — an
|
||||
invented bonus would be worse than a missing one.
|
||||
|
||||
This stays a near-range reading. A raid member the client has not loaded
|
||||
has no readable equipment at all, and their column stays `?`.
|
||||
|
||||
### The weapon-buff column could never report a missing buff
|
||||
|
||||
For another player, the client returns *nothing* for the weapon
|
||||
enchantment when there is no imbue — not an empty string, as the code
|
||||
expected. So everyone without a weapon buff was shown as `?` instead of as
|
||||
a gap, and was left out of the gap count, the footer and the whisper.
|
||||
Measured in a 26-man raid: **14 of 25** players were mislabelled that way —
|
||||
precisely the case a buff checker exists to report.
|
||||
|
||||
The fix distinguishes by readability: if the main hand can be read and
|
||||
there is no imbue, that is a gap. If the player cannot be read, it stays
|
||||
unknown. Unknown is still never silently turned into missing.
|
||||
|
||||
### Consumables that were being discarded
|
||||
|
||||
Six buffs were tracked in the tables but never recognised, because the
|
||||
aura carries a different name than the item: **Elixir of the Giants**,
|
||||
**Elixir of Greater Agility**, **Elixir of Fortitude**, **Strike of the
|
||||
Scorpok**, **Rage of Ages** and **Elixir of Greater Frost Power**. In one
|
||||
raid, `Elixir of the Giants` alone was thrown away 38 times.
|
||||
|
||||
Aura names also arrive from the client with trailing spaces on occasion,
|
||||
which defeated the name match; they are trimmed now.
|
||||
|
||||
### "Gaps only" no longer empties Hit and Resistances
|
||||
|
||||
Those two tabs are numeric — no cell there can be *missing*, so the filter
|
||||
hid every row. It now also counts the unknown cells, which is what there is
|
||||
to see on those tabs.
|
||||
|
||||
### The coverage number belongs to the tab it is shown on
|
||||
|
||||
The pill counted the players whose **auras** could be read — and showed
|
||||
that number on every tab. Auras are readable raid-wide, equipment and hit
|
||||
only nearby, resistances only for yourself. In the same raid the pill
|
||||
claimed `26/26` while the Hit tab really knew 15 of 26 and the Resistances
|
||||
tab 1 of 26.
|
||||
|
||||
Each tab now reports its own reading, and says which one it is:
|
||||
`26/26 readable` on the aura tabs, `15/26 gear read`, `15/26 hit read`,
|
||||
`1/26 resist read`. The report line in chat carries the same number. As a
|
||||
side effect the word "readable" now means one thing instead of two.
|
||||
|
||||
## v0.6.0
|
||||
|
||||
### Hit
|
||||
|
||||
A new **Hit** tab, and with it the addon's second numeric tab after
|
||||
Resistances. Eight columns: melee, ranged, and one per spell school —
|
||||
because talents and items raise schools individually, so one "spell hit"
|
||||
number would be wrong for most casters.
|
||||
|
||||
There is **no hit API in 1.12**. The number is assembled from what can
|
||||
actually be read:
|
||||
|
||||
- **items** — parsed out of the equipped items' tooltips
|
||||
- **set bonuses** — counted **once per set**, only when the piece
|
||||
threshold is met (the bonus line is printed on every piece of the set,
|
||||
so adding it per item would multiply it)
|
||||
- **hit auras** — buffs that grant hit
|
||||
- **talents** — for your own character, and for other players over the
|
||||
inspect protocol this server ships (see below)
|
||||
- **weapon skill** — every point above 300 is worth 0.2% hit against a
|
||||
+3-level boss
|
||||
|
||||
The cell tooltip shows that as a plain **addition**: one row per source,
|
||||
values in a right-aligned column, so the total can be checked by adding it
|
||||
up. Sources that contribute nothing are still listed at `+0.0%` — a missing
|
||||
row would look like a forgotten source. A source that could not be **read**
|
||||
shows `?`, never `+0.0%`: unknown is not zero.
|
||||
|
||||
The boss's requirement is stated as one flat number (`Cap vs a +3-level
|
||||
boss`). It does not move with your weapon skill — skill counts on the
|
||||
player's side of the comparison, where it belongs.
|
||||
|
||||
Caps: melee 8% at 300 weapon skill, dual-wield white swings 27%, spell 16%.
|
||||
A cell at or above its cap is marked green.
|
||||
|
||||
### Reading other players' talents
|
||||
|
||||
Talents raise hit by up to several percent, so a hit number without them is
|
||||
systematically low. WoW 1.12 has no foreign-talent channel and this server
|
||||
transmits none either — but it ships **its own inspect protocol**, a plain
|
||||
addon-message conversation: we ask by name, the target's client answers with
|
||||
its talent tree.
|
||||
|
||||
DopingControl uses exactly that, for the players the scan already shows.
|
||||
One request per player, at most one every five seconds, and each name at
|
||||
most once per half hour. It can be switched off entirely with
|
||||
`/dc talents off`.
|
||||
|
||||
### Weapon skill books
|
||||
|
||||
A quest weapon-skill book grants +3 skill — about 0.6% hit — and **cannot be
|
||||
detected on another player**: no channel reports foreign weapon skills. So
|
||||
it is entered by hand, in a new **Skill books** options tab: a grid with one
|
||||
row per scanned player and one column per weapon skill, with a checkbox
|
||||
wherever that class could own a book for it.
|
||||
|
||||
### Whisper on the Hit tab
|
||||
|
||||
The hit tab now offers the per-player whisper button, unlike the other
|
||||
display tab: being short of the hit cap is something that player can fix,
|
||||
a resistance total is not. The whisper carries both numbers —
|
||||
`Melee hit 5.0/8.0` — so the reader knows the distance, not just the fact.
|
||||
|
||||
It only ever mentions the columns that **role** is asked about: a melee
|
||||
player is never told about his shadow hit, and healers are never whispered
|
||||
at all (heals cannot miss). Every column stays visible with its own cap
|
||||
marking on the tab — the display hides nothing, only the whisper is
|
||||
selective.
|
||||
|
||||
### Class buffs
|
||||
|
||||
A sixth slot: **Emerald Blessing**. It ships with no expectation default —
|
||||
it is a raid quest reward almost nobody carries — so its column stays
|
||||
hidden until you enable it per role and class. Its +1% spell hit counts on
|
||||
the Hit tab either way.
|
||||
|
||||
### Tables
|
||||
|
||||
- **Alternating row shading** in every table (main window, both options
|
||||
grids), so a row can be followed across a wide grid.
|
||||
- The **options window width follows the selected tab** instead of being
|
||||
fixed to the widest one.
|
||||
- The options column headers now use the **same header tiles as the main
|
||||
window** — three-letter label over a sub-line, in a bordered strip.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Could not scroll to the bottom** of the main window once every role
|
||||
group was expanded. The content height was right; the scrollbar was
|
||||
never told about it, so it kept the maximum it had when the group was
|
||||
still collapsed.
|
||||
- An unreadable equipment row was labelled **"out of range"** even when
|
||||
distance was not the cause. It now states what was actually observed —
|
||||
that no equipment slot returned an item link — and prints the measured
|
||||
distance separately.
|
||||
- **"Not expected for role X"** was shown for cells decided by class or by
|
||||
the item (a shaman has no ranged enchant slot; an empty exemptable slot),
|
||||
and pointed at an options switch that cannot change them. Those cells now
|
||||
give the real reason.
|
||||
- The hit-column header claimed the number was summed from items alone,
|
||||
while it also contained auras and talents.
|
||||
|
||||
### Test mode
|
||||
|
||||
`/dc test` now simulates a **40-player raid** in eight subgroups instead of
|
||||
25 players, including deliberately unreadable players and a completely
|
||||
unreadable group.
|
||||
|
||||
## v0.5.2
|
||||
|
||||
New **Resistances tab**: display-only totals for all five schools per
|
||||
player with a readable-players raid average in the footer. Equipment
|
||||
semantics finalized: an empty slot counts as a gap unless it is one that may
|
||||
legitimately be empty (off hand, ranged), the expectation grid governs
|
||||
enchants only, and neck/rings joined the enchant logic (enchantable
|
||||
on this server; expectation defaults to off). Expectation storage now
|
||||
distinguishes a deliberate uncheck from a never-seen slot, so slots added in
|
||||
future versions appear automatically.
|
||||
|
||||
## v0.5.1
|
||||
|
||||
The Equipment tab now covers all sixteen slots: neck and both rings joined
|
||||
as item tiles (quality border, tooltip, empty slot counts as a gap — no
|
||||
enchant exists for them in vanilla, so they carry no corner marker).
|
||||
|
||||
## v0.5.0
|
||||
|
||||
First public release: the four-tab readiness matrix (Consumables / Class
|
||||
buffs / Debuffs / Equipment), the HAS–MISSING–UNKNOWN honesty model with
|
||||
coverage pill and last-known display, the five-role system with
|
||||
auto-suggestion and per-character confirmation, the role × class
|
||||
expectations grid, per-player whispers with cooldown, the raid report with
|
||||
mandatory preview, ready-check and window-open scan automation, and the
|
||||
deterministic test mode.
|
||||
Reference in New Issue
Block a user