Portal Pro

Portal Pro is the single most advanced addon for mages to sell portals and track their income. Massive customization, ledgers, market analysis, reagent cost and count tracking and more! Actively being developed and improved.
Back to Files

PortalPro-V1.2.2.zip

File namePortalPro-V1.2.2.zip
Uploader
0x29a0x29a
Uploaded
Jul 31, 2026
Downloads
10
Size
1.4 MB
Flavors
ClassicClassic TBC
File ID
8549280
Type
R
Release
Supported game versions
  • 2.5.6
  • 2.5.5
  • 2.5.4
  • 1.15.9
  • 1.15.8
  • 1.15.7
  • 1.15.6

What's new

Changelog

[V1.2.1]

  • Added About section
  • Added version tracking
  • Corrected some visual aberrations
  • Improved performance

[V1.2.0]

  • Corrected an issue force rotating ads. Ads now broadcast singularly, properly.

[V1.2.0]

Added

  • A paid lead is removed from the queue. Handled by the Leads module subscribing to PAYMENT_RECEIVED rather than by each payment watcher mutating the lead directly, so trades and mail now behave identically — mail payments previously left the card sitting there. Their per-player cooldown is cleared on the way out, so a repeat request inside the five-minute window still produces a fresh card instead of being suppressed.
  • Live market intelligence. The lead scanner already read every rival advert in order to reject it as a customer; those adverts contain prices. Keeping them turns a filter into a price feed. New Market tab shows what the competition is asking, what customers are offering, and how your pricing compares per destination. A live line on the Ads tab shows the Trade median next to your price while you're editing the ad. /pp market.
    • Asks and bids are tracked separately — a mage advertising is competition, a customer naming a price is demand. They answer different questions.
    • The median counts one observation per advertiser, not per message. Without that, whoever spams hardest defines the "market rate".
    • Price parsing handles 10g, 1g50s, 75 silver, 12 gold, and multi-price lines (taking the low end, which is what customers compare against). Bounded to 10s–200g to reject boasts and unrelated item prices. Realm-tagged.
    • 18 parser cases verified, including rejecting WTS Arcanite Bar 200g, portal room, and 1st port free.
  • Sandbox gained Inject market data, which pushes sample adverts through the real classifier rather than writing observations directly.
  • Money is shown in full gold/silver/copper everywhere a balance appears — header, compact bar, ledger, stats. Previously collapsed to a single rounded unit (12.3g), which is fine for a chart axis and misleading for a balance. Chips widened to fit.
  • Excluding non-business portals. Portals cast for a dungeon group were being billed against your margin as a reagent cost. Three layers of control:
    • Casts inside a dungeon or raid are no longer logged (on by default, IsInInstance).
    • Per-destination exclusion under Settings → Tracking.
    • Free-cast mode (/pp free) suspends logging entirely. Session-only by design — a forgotten flag surviving a relog would quietly stop recording income. Shown as "NOT LOGGING" in the header whenever tracking is suspended for any reason.
    • /pp oops retroactively untracks the portal you just cast and removes its rune cost.
    • Per-row delete in the Ledger, arm-then-confirm so a payment can't vanish on a stray click.
  • Untracked casts are counted separately (personalCasts) rather than discarded, and are excluded from the Portals figure so it matches what the ledger charged you for.
  • Auto-uninvite now skips untracked casts — it would otherwise have kicked your dungeon party 20 seconds after opening their portal.

Fixed

  • Market tab buttons did nothing. MARKET_UPDATED was fired by every market mutation but no UI code subscribed to it, so removing an advert, ignoring an advertiser and clearing the data all worked on the data and never redrew the screen. PRICES_CHANGED and FREEMODE_CHANGED had the same gap. Audited every fired event against its subscribers; the remaining unsubscribed ones are informational or covered by a ticker.

  • Removing an advert now matches on the observation itself rather than its id, so records saved before ids existed can still be removed. Missing ids are backfilled once on load.

  • Goods listings were being counted as portal prices. An enchanter's multi-item advert that mentioned a portal in passing was booked as a 1g "competitor ask", dragging the median down and making the addon report that you were undercutting everyone. Four defences added, cheapest first:

    • Messages containing an item or enchant link (|H) are rejected outright — that's someone selling goods.
    • Three or more distinct prices with no city named is a shop listing. A mage who genuinely quotes per-city prices names the cities, so WTS ports: SW 10g, IF 12g, Darn 15g still counts.
    • A price must sit within 40 characters of the word "port" to be read as its price.
    • The price used is now the one nearest the portal mention rather than the cheapest, so ports 5g, teles 3g reports 5g — the portal price — instead of the teleport's.
    • 14 parser cases verified.
  • You can now remove adverts from the figures by hand, because no classifier catches everything. Each row on the Market tab has X (drop this line) and ! (ignore this advertiser entirely, and forget what they've already posted). Ignored advertisers are counted on the tab with a reset.

  • Full advert text is visible. Rows are too narrow for a chat line, so hovering shows the complete message, side, price and channel. Stored text was also raised from 120 to 255 characters so nothing is lost from the record in the first place.

  • Trade payments were being missed entirely. The money claim only armed when TRADE_ACCEPT_UPDATE reported both parties accepted — but when the second party accepts, the server settles immediately and the client usually goes straight to TRADE_CLOSED without ever firing that update. No claim, no capture, sale lost. This was listed as a "known unknown" and is now confirmed wrong against a real trade. The claim now arms as soon as money appears in the trade window, which can't happen on an empty trade and is always well before the delta arrives. ERR_TRADE_COMPLETE is used as positive confirmation to extend the window when it fires, and TRADE_CLOSED leaves a grace period rather than deciding an outcome it can't see.

  • port to UC from Org resolved to Orgrimmar. Longest-alias-wins picked org (3 chars) over uc (2), quoting the wrong city and booking the wrong destination. Resolution is now position-aware: a city after "to" wins outright, a city after "from" is treated as the origin and excluded. 13 cases verified.

  • /pp paid <name> <amount> [city] records a payment by hand, for anything the automatic capture still misses. It fires the same event as a real trade, so the lead clears and the stats update identically.

  • Casting a Teleport announced "portal is up - hop in!" to the party. Teleport moves only the caster, so there was nothing for anyone to hop into. Both PORTAL_CAST consumers in Group.lua accepted the cast kind and neither checked it — the auto-uninvite handler had the same defect and would have cleared the group after a self-teleport.

  • Teleports are no longer counted as a business cost by default, for the same reason: a spell that relocates only you can never be a sale, so charging its Rune of Teleportation against your margin makes the ledger lie. Settings → Tracking has a switch for anyone who wants to account for travel to their selling spot.

  • Lead toast appeared and vanished instantly. AnimationGroup:Stop() fires OnFinished with requested = true, so interrupting a fade-out ran that fade's completion callback — hiding the frame — and the replacement fade-in then played on an already-hidden frame. OnFinished now ignores interrupted animations, and the stale handler is detached before stopping.

  • UI:SlideIn created a fresh AnimationGroup on every call (leaking one per toast) and its Alpha animation competed with UI:Fade on the same frame. It's now translation-only and reuses a single group.

  • Lead card message text ran underneath the Whisper / Quote / Invite buttons. It's now anchored to the leftmost button, so it reclaims the space when the window is widened.

  • Stat tile sub-lines had no right anchor and drew straight past the tile border. All three lines are now bounded, and sub-lines wrap to a second line instead of clipping.

  • Destination breakdown values could grow leftwards over their own bar.

Changed

  • The lead toast is suppressed during combat and replayed on leaving it. If combat starts while a toast is up, it's pulled and the lead is held rather than lost. Newest lead shows first with a "+N more waiting" count; leads that expired during the fight are dropped. The alert sound is unaffected and still fires immediately.
  • Conversion tile is labelled "(session)" rather than prefixing its sub-line, which is what was overflowing.

Initial build. Not yet run in a live game session — see "Known unknowns" below.

Added

  • Leads — chat scanner across Say, Yell, General, Trade, LFG, Guild, Party and Whisper. Intent is scored against a weighted rule set instead of a substring match, so competitors advertising ("wts ports") and incidental mentions ("the portal room") don't generate leads. Destination parsing from abbreviations. Per-player cooldown, blacklist, VIP list, returning-customer detection, expiry.
  • Ads — multiple templates with sequential or random rotation, {price}-style variables, raid-icon picker inserting {rt1}{rt8}, colour codes, live preview rendered as chat will show it, 255-character validation.
  • Broadcasting — Blizzard requires a hardware event for Say/Yell/Channel, so sends come from the Broadcast button, a keybind, or opt-in arm mode which releases the staged ad on your next keypress. Per-channel throttle with a cooldown indicator.
  • Whispers — seven templates (greeting, quote, location, invited, portal-up, thanks, busy) with variable expansion and quick-reply buttons on each lead card.
  • Ledger — append-only. Payments captured from trades and mail via a single PLAYER_MONEY arbiter so no transaction is double-booked. Refunds are linked negative entries that never edit the original sale. Rune consumption recorded as cost basis. CSV export.
  • Stats — net/gross/refunds/reagents, gold per hour on an idle-pausing session clock, leads→invited→paid funnel, 7-day chart, destination breakdown, top customers.
  • Interface — custom widget kit on design tokens, no Blizzard chrome. Resizable and scalable main window, compact always-on bar, lead toasts, minimap button.
  • Ops — rune counter with low-stock warning, party announce on cast, optional group cleanup, Hardcore rescue-zone highlighting on zone-local channels.
  • Sandbox (/pp sandbox) — injects synthetic leads, payments, refunds and casts, and scores arbitrary chat lines, so the parser and ledger can be exercised without customers.
  • Font picker supporting bundled Inter / Noto Sans (both OFL) with probe-based fallback.
  • CurseForge / Wago / WoWInterface packaging via the BigWigs packager.

This mod has no additional files