Skip to content

fix(seller): stop price override items from bypassing every filter - #35

Merged
icemansparks merged 1 commit into
merkerhoodfrom
fix/override-items-bypass-filters
Aug 25, 2026
Merged

fix(seller): stop price override items from bypassing every filter#35
icemansparks merged 1 commit into
merkerhoodfrom
fix/override-items-bypass-filters

Conversation

@icemansparks

Copy link
Copy Markdown
Collaborator

Reported: Twin Blades of Azzinoth (bind on pickup) showed up in the auction house. No BoP item should ever be listed.

Root cause

The seller has two independent sources of items, and only one of them is filtered.

  • AHBConfig::InitializeBins() applies every filter — bind type, class, level, req level/skill, vendor/loot/other, conjured/gems/keys/lootable, mod_auctionhousebot_disabled_items, SellerWhiteList — and puts the survivors into the per-quality bins.
  • AHBConfig::LoadPriceOverrides() loads mod_auctionhousebot_priceOverride raw, with no filtering whatsoever.
  • GetItemsToSell() builds its two priority blocks by iterating config->itemPriceOverrides directly, so those items never went through the bins.
  • In Sell() the only gates on such a pick are the per-item count cap, "does a prototype exist", and Quality > AHB_MAX_QUALITY. No bind check. No disabled-items check. No whitelist check.

Net effect: a row in the price override table was an unconditional licence to list the item. With ~11.5k override rows, that is a wide hole.

Two consequences worth calling out:

  1. AuctionHouseBot.Bind_When_Picked_Up = 0 was silently ignored for every override item — the reported BoP weapon.
  2. Rows added to mod_auctionhousebot_disabled_items did nothing for any item that also has a price override, so blacklisting alone could not fix it.

Fix

InitializeBins() now records every item that passed its tests in a new SellableItems set (the union of the bins — one insert at the point an item is accepted), and both priority blocks skip anything that is not in it:

if (!config->IsSellableItem(itemID))
{
    continue;
}

A price override is a price, not a permission to sell. Blocks 3 and 4 are bin-sourced and were always filtered — unchanged. Every filter now applies uniformly, and the disabled-items blacklist becomes effective on the override path too.

Verification

  • Traced in code; the two priority loops were the only sell-side consumers of itemPriceOverrides (GetPriceOverrideForItem() is pricing only).
  • Confirmed against the deployed config: the merkerhood config matrix sets no Bind_* overrides, so LIVE runs the .dist default Bind_When_Picked_Up = 0 — BoP was supposed to be excluded already.
  • Full module compile: the core-build workflow on this PR.
  • Not yet run on testcore (worldserver there is stopped; left as found).

To see the scale of what was leaking on the realm:

SELECT i.entry, i.name, i.Quality, i.bonding
FROM mod_auctionhousebot_priceOverride p
JOIN item_template i ON i.entry = p.item
WHERE i.bonding = 1
ORDER BY i.Quality DESC, i.name
LIMIT 50;

Everything that query returns is what the bot could previously list and can no longer list.

Cleanup after merge

Auctions already listed are unaffected by this change — they stay until they expire or sell. .ahbotoptions ahexpire <ahMapID> clears the bot's existing auctions if you want the BoP gear gone immediately rather than in up to 24 hours.

InitializeBins() is where the bind, class, level, quality, disabled item and
whitelist filters are applied, and it feeds the per-quality bins. The price
override map is loaded separately by LoadPriceOverrides() with no filtering at
all, and GetItemsToSell() builds its two priority blocks straight from that map.
Sell() then only checks the per-item count cap, that a prototype exists and that
the quality is in range - so any item holding a row in
mod_auctionhousebot_priceOverride got listed no matter what the filters said.

That is how bind on pickup gear (Twin Blades of Azzinoth) reached the auction
house while AuctionHouseBot.Bind_When_Picked_Up was 0, and it also meant rows
added to mod_auctionhousebot_disabled_items had no effect on any item that had a
price override.

InitializeBins() now records every item that passed its tests in SellableItems,
and the two priority blocks skip anything that is not in it. A price override is
a price, not a permission to sell. The bin-sourced blocks were always filtered
and are unchanged.
@icemansparks
icemansparks merged commit 620a978 into merkerhood Aug 25, 2026
1 check passed
@icemansparks
icemansparks deleted the fix/override-items-bypass-filters branch August 25, 2026 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant