diff --git a/GrepolisRemoteControl.user.js b/GrepolisRemoteControl.user.js index a18f4e0..7e1fb68 100644 --- a/GrepolisRemoteControl.user.js +++ b/GrepolisRemoteControl.user.js @@ -792,47 +792,59 @@ async function executeScanMarket(cmd) { const { town_id } = cmd; - const reactionMs = randInt(1500, 3000); - log(`Waiting ${reactionMs}ms before scanning market...`); - await sleep(reactionMs); - + await sleep(randInt(1500, 3000)); if (paused) return { ok: false, msg: 'Aborted due to pause/captcha' }; return new Promise((resolve) => { - uw.gpAjax.ajaxPost('frontend_bridge', 'execute', { + 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); + }; + + // Trigger the getData + origAjaxPost('frontend_bridge', 'execute', { model_url: 'BuildingMarket', action_name: 'getData', arguments: { - limit: 20, - offset: 0, - demand_type: 'all_but_gold', - offer_type: 'all_but_gold', - max_ratio: 3, - max_delivery_time: 172800, - visibility: 2, - order_by: 'ratio', - order_direction: 'desc' + limit: 20, offset: 0, + demand_type: 'all_but_gold', offer_type: 'all_but_gold', + max_ratio: 3, max_delivery_time: 172800, + visibility: 2, order_by: 'ratio', order_direction: 'desc' }, town_id: town_id, nl_init: true - }, false, { - success: async function(resp) { - try { - // Send the data back to our backend - await fetch(`${BASE_URL}/api/market_data?player_id=${uw.Game.player_id}`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(resp) - }); - resolve({ ok: true, msg: 'Market scanned and data uploaded' }); - } catch (e) { - resolve({ ok: false, msg: 'Failed to upload market data: ' + e }); - } - }, - error: function() { - resolve({ ok: false, msg: 'Failed to fetch market data from game' }); - } }); + + // Timeout after 15 seconds + timeoutId = setTimeout(() => { + if (!intercepted) { + uw.gpAjax.ajaxPost = origAjaxPost; // restore + resolve({ ok: false, msg: 'Market scan timed out' }); + } + }, 15000); }); } diff --git a/static/js/api.js b/static/js/api.js index 460081d..d80e460 100644 --- a/static/js/api.js +++ b/static/js/api.js @@ -77,7 +77,7 @@ window.updateClientStatus = function(online) { el.className = 'conn-badge offline'; } // Enable/disable the Send button - const btn = document.querySelector('#command-form-wrap .btn-gold'); + const btn = document.getElementById('btn-send'); if (btn) { btn.disabled = !online; btn.title = online ? '' : 'Script is offline â cannot send commands'; diff --git a/static/js/components/commandForm.js b/static/js/components/commandForm.js index 3b08b7c..a7dd21b 100644 --- a/static/js/components/commandForm.js +++ b/static/js/components/commandForm.js @@ -12,7 +12,7 @@ window.onCmdTypeChange = function() { }; // Building emoji icons for the visual grid -const BUILDING_ICONS = { +window.BUILDING_ICONS = { main: 'đī¸', storage: 'đī¸', farm: 'đž', academy: 'đ', temple: 'âŠī¸', barracks: 'âī¸', docks: 'â', market: 'đ', hide: 'đŗī¸', lumber: 'đĒĩ', stoner: 'đǍ', ironer: 'âī¸', wall: 'đ§ą' @@ -35,7 +35,7 @@ window.openBuildingModal = function() { grid.innerHTML = Object.entries(window.BUILDING_NAMES_GR).map(([key, nameGr]) => { const level = bLevels[key] !== undefined ? bLevels[key] : '?'; const data = bData[key]; - const icon = BUILDING_ICONS[key] || 'đī¸'; + const icon = window.BUILDING_ICONS[key] || 'đī¸'; const isSelected = key === window.selectedBuildingId; if (!data) { diff --git a/templates/dashboard.html b/templates/dashboard.html index d7840e3..6a0422d 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -223,7 +223,7 @@ - +