diff --git a/GrepolisRemoteControl.user.js b/GrepolisRemoteControl.user.js index 7e1fb68..e41e8a9 100644 --- a/GrepolisRemoteControl.user.js +++ b/GrepolisRemoteControl.user.js @@ -799,32 +799,45 @@ let intercepted = false; let timeoutId; - // Wrap gpAjax to intercept ANY response that looks like market data const origAjaxPost = uw.gpAjax.ajaxPost.bind(uw.gpAjax); - uw.gpAjax.ajaxPost = function(controller, action, params, loader, callbacks) { - const wrappedCallbacks = callbacks && typeof callbacks === 'object' ? { - success: function(resp) { - // Market data has an 'offers' array - if (!intercepted && resp && resp.offers) { - intercepted = true; - clearTimeout(timeoutId); - uw.gpAjax.ajaxPost = origAjaxPost; // restore - fetch(`${BASE_URL}/api/market_data?player_id=${uw.Game.player_id}`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(resp) - }) - .then(() => resolve({ ok: true, msg: `Market scanned: ${resp.offers.length} offers` })) - .catch(e => resolve({ ok: false, msg: 'Upload failed: ' + e })); - } - if (callbacks.success) callbacks.success(resp); - }, - error: callbacks.error - } : callbacks; - return origAjaxPost(controller, action, params, loader, wrappedCallbacks); + + // Handle BOTH Grepolis callback styles: + // Style A: ajaxPost(ctrl, action, params, loader, {success, error}) + // Style B: ajaxPost(ctrl, action, params, loader, fnSuccess, fnError) + uw.gpAjax.ajaxPost = function(controller, action, params, loader, cbSuccessOrObj, cbError) { + const handleResp = function(resp) { + log(`[Market intercept] ctrl:${controller} action:${action} has_offers:${!!(resp && resp.offers)}`); + if (!intercepted && resp && resp.offers) { + intercepted = true; + clearTimeout(timeoutId); + uw.gpAjax.ajaxPost = origAjaxPost; + fetch(`${BASE_URL}/api/market_data?player_id=${uw.Game.player_id}`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(resp) + }) + .then(() => resolve({ ok: true, msg: `Market scanned: ${resp.offers.length} offers` })) + .catch(e => resolve({ ok: false, msg: 'Upload failed: ' + e })); + } + }; + + if (cbSuccessOrObj && typeof cbSuccessOrObj === 'object') { + // Style A — object with success/error keys + const origSuccess = cbSuccessOrObj.success; + return origAjaxPost(controller, action, params, loader, { + success: function(resp) { handleResp(resp); if (origSuccess) origSuccess(resp); }, + error: cbSuccessOrObj.error + }); + } else { + // Style B — separate function args + return origAjaxPost(controller, action, params, loader, + function(resp) { handleResp(resp); if (typeof cbSuccessOrObj === 'function') cbSuccessOrObj(resp); }, + cbError + ); + } }; - // Trigger the getData + // Trigger getData through frontend_bridge origAjaxPost('frontend_bridge', 'execute', { model_url: 'BuildingMarket', action_name: 'getData', @@ -841,7 +854,7 @@ // Timeout after 15 seconds timeoutId = setTimeout(() => { if (!intercepted) { - uw.gpAjax.ajaxPost = origAjaxPost; // restore + uw.gpAjax.ajaxPost = origAjaxPost; resolve({ ok: false, msg: 'Market scan timed out' }); } }, 15000);