Skip to content

feat(market): add asynchronous web market order queue processor (IOMarket::processWebOrders) - #909

Open
berrytern wants to merge 14 commits into
zimbadev:mainfrom
berrytern:feat/web-market-order-queue
Open

feat(market): add asynchronous web market order queue processor (IOMarket::processWebOrders)#909
berrytern wants to merge 14 commits into
zimbadev:mainfrom
berrytern:feat/web-market-order-queue

Conversation

@berrytern

@berrytern berrytern commented Aug 18, 2026

Copy link
Copy Markdown

Description

Integrating web-based marketplace purchases and sales with an active OpenTibia game server has historically been challenging due to the "dual-truth" memory problem:

  • Modifying an online player's gold (balance) or inventory directly in MySQL leads to silent rollbacks when the C++ server saves the player's RAM state.
  • Forcing players to always log out before buying/selling items on the website degrades the user experience.

This PR implements an Asynchronous Outbox Order Queue System directly in IOMarket::processWebOrders:

  • A new table market_web_orders holds queued purchase requests submitted from web portals / AACs / APIs.
  • The C++ engine polls pending orders on a configurable interval (default: 2000ms) on the Dispatcher thread.
  • Hybrid RAM/DB Execution:
    • If buyer or seller is ONLINE: Modifies live player memory (player->getBankBalance(), player->setBankBalance(), internalAddItem()) and notifies the player in-game via text message.
    • If buyer or seller is OFFLINE: Safely executes atomic SQL balance debit/credit and delivers items directly into the player's depot inbox (player_depotitems).
  • Automatically updates active market_offers and logs transaction history in market_history.

Behaviour

Actual

  • Web market purchases required either fragile external database scripts or forced players to be offline, frequently causing memory overwrite bugs or 409 conflict rejections.

Expected

  • External websites insert a row into market_web_orders with status 'PENDING'.
  • The engine processes the order within ~1-2 seconds, atomically updating RAM (if players are online) or database (if players are offline), delivering items to Depot/Inbox, deducting/crediting gold or Tibia Coins, and marking the order 'COMPLETED'.
  • Zero race conditions, zero rollbacks, and zero duplicated items.

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How Has This Been Tested

Test A: Web purchase with offline buyer and seller

  1. Create a market offer:
    INSERT INTO market_offers (player_id, sale, itemtype, amount, created, anonymous, price, tier) VALUES (5, 1, 3360, 1, UNIX_TIMESTAMP(), 0, 15000, 0);
  2. Insert a pending order in market_web_orders:
    INSERT INTO market_web_orders (offer_id, buyer_id, buyer_account_id, seller_id, seller_account_id, itemtype, amount, price, tier, currency_type, status, created_at) VALUES (LAST_INSERT_ID(), 4, 1, 5, 1, 3360, 1, 15000, 0, 'gold', 'PENDING', UNIX_TIMESTAMP());
  3. Observe engine execution.
  4. Result:
    • Order status transitions to 'COMPLETE

ℹ️ PR Dependency Note

This PR (feat/web-market-order-queue) is stacked on top of #908 (feat/player-concurrency-lock):

Merge Order:
Please review and merge #908 first.

@berrytern
berrytern force-pushed the feat/web-market-order-queue branch from a22aaae to 20bca68 Compare August 19, 2026 02:12
@jprzimba

Copy link
Copy Markdown
Collaborator

Check Linux build error and fix please

@berrytern
berrytern force-pushed the feat/web-market-order-queue branch from 3edce21 to 26b8f4f Compare August 19, 2026 18:26
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.

2 participants