From 1b2319635dd89577858f0e713134d5ffe7c475e0 Mon Sep 17 00:00:00 2001 From: funman300 Date: Sat, 1 Aug 2026 21:05:25 -0700 Subject: [PATCH] fifa17-recon: fix store transaction wrongly auto-opening packs store/transaction receives {"state":"TRANSACTIONCANCEL"} (cancel/close) and {"packId":N} (pack-details fetch on store load) -- neither is a confirmed purchase. The handler treated packId as a buy and even defaulted to opening a Gold Pack on cancels, silently spending coins. Make store_buy a safe no-op that logs every body, so the real purchase-CONFIRM signal can be identified from a deliberate in-game buy and open_pack() gated on exactly that. Save restored on next fresh run. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01PN5bmpDVQR1aXgefyWAt7o --- fifa17-recon/tools/utas_server.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/fifa17-recon/tools/utas_server.py b/fifa17-recon/tools/utas_server.py index e199c4c..e7d0f28 100755 --- a/fifa17-recon/tools/utas_server.py +++ b/fifa17-recon/tools/utas_server.py @@ -219,21 +219,19 @@ def store_catalog(h): def store_buy(h): - # PUT (v2) store/transaction -> buy + open a pack; return the awarded items. - pid = None + # PUT (v2) store/transaction. SAFE NO-OP until the real purchase-CONFIRM signal + # is reversed. Observed bodies are NOT confirmed buys: + # {"state":"TRANSACTIONCANCEL"} = cancel/close the store + # {"packId":N} = fetch a pack's details when the store loads + # Opening a pack on either wrongly spent coins. Log every body so we can spot + # the real confirm body when the user makes a DELIBERATE purchase, then gate + # open_pack() on exactly that. (open_pack lives in fut_store, ready to wire.) try: body = json.loads(h._body.decode()) if getattr(h, "_body", b"") else {} - for k in ("packId", "productId", "id", "pack"): - if isinstance(body.get(k), int): - pid = body[k]; break except Exception: body = {} - pack = pack_by_id(pid) or PACK_CATALOG[1] # default Gold Pack - items = STORE.open_pack(pack["price"], pack["count"], pack["gold"]) - if items is None: - return 461, {"reason": "insufficient_coins", "credits": STORE.coins()} - return 200, {"itemData": items, "coins": STORE.coins(), - "currencies": [{"name": "coins", "value": STORE.coins()}]} + log(" STORE txn body=%r (no-op; buy-confirm flow not reversed yet)" % body) + return 200, {} def purchased_items(h):