From 51d15118edd49f696345ecd1f0715f3f0e9d7136 Mon Sep 17 00:00:00 2001 From: haunter Date: Wed, 6 May 2026 23:56:01 +0300 Subject: [PATCH] fix 2 --- bot_modules/04d_execute_culture.js | 78 +++++++++++------------------- bot_modules/05_main.js | 3 ++ 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/bot_modules/04d_execute_culture.js b/bot_modules/04d_execute_culture.js index 24ff05e..5c7b9c3 100644 --- a/bot_modules/04d_execute_culture.js +++ b/bot_modules/04d_execute_culture.js @@ -6,14 +6,17 @@ // 'party' → Γιορτή πόλης (costs wood/stone/iron) // 'triumph' → Παρέλαση θριάμβου (costs battle points) // -// On success/failure, reports back to /api/commands//result -// so the culture_log row is updated from 'pending' to 'success'/'failed'. +// Uses the same fire-and-forget ajaxPost pattern as all other +// execute modules in this codebase (04a, 04b, 04c). // ================================================================ async function executeCultureCommand(cmd) { if (!cmd || !cmd.id || !cmd.payload) return; - const { celebration_type, town_id } = cmd.payload; + // town_id lives on the command root (like build/recruit), payload has celebration_type + const town_id = cmd.town_id || cmd.payload.town_id; + const celebration_type = cmd.payload.celebration_type; + if (!celebration_type || !town_id) { reportResult(cmd.id, 'failed', 'Invalid culture payload: missing celebration_type or town_id'); return; @@ -24,9 +27,10 @@ async function executeCultureCommand(cmd) { return; } - log(`[αγορά] Εκτέλεση ${celebration_type === 'party' ? 'Γιορτής πόλης' : 'Παρέλασης θριάμβου'} για πόλη ${town_id}`); + const label = celebration_type === 'party' ? 'Γιορτή πόλης' : 'Παρέλαση θριάμβου'; + log(`[αγορά] Εκτέλεση ${label} για πόλη ${town_id}`); - // Validate town still exists in game memory + // Validate town exists in game memory const town = uw.ITowns?.towns?.[town_id]; if (!town) { reportResult(cmd.id, 'failed', `Η πόλη ${town_id} δεν βρέθηκε στη μνήμη του παιχνιδιού.`); @@ -44,58 +48,32 @@ async function executeCultureCommand(cmd) { && a.celebration_type === celebration_type && (a.finished_at ?? 0) > nowTs) { reportResult(cmd.id, 'failed', - `${celebration_type === 'party' ? 'Γιορτή' : 'Παρέλαση'} ήδη ενεργή στην πόλη ${town_id}.`); + `${label} ήδη ενεργή στην πόλη ${town_id}.`); return; } } } - } catch (e) { /* model not loaded — proceed anyway, server will error if invalid */ } + } catch (e) { /* model not loaded — proceed; server already validated */ } - // Fire the Grepolis AJAX - let ajaxSuccess = false; - let ajaxError = null; + // Human-like reaction delay — same as all other executors + const reactionMs = randInt(800, 2500); + log(`[αγορά] Waiting ${reactionMs}ms (reaction time)...`); + await sleep(reactionMs); - await new Promise(resolve => { - try { - uw.gpAjax.ajaxPost( - 'building_place', - 'start_celebration', - { - town_id: parseInt(town_id, 10), - celebration_type: celebration_type - }, - false, // no cache-busting - // success callback - () => { - ajaxSuccess = true; - resolve(); - }, - // error callback - (err) => { - ajaxError = err ? JSON.stringify(err) : 'Άγνωστο σφάλμα AJAX'; - resolve(); - } - ); - } catch (e) { - ajaxError = String(e); - resolve(); - } + if (paused) { + reportResult(cmd.id, 'failed', 'Aborted due to pause/captcha'); + return; + } - // Safety timeout: if neither callback fires within 12 s, treat as failed - setTimeout(() => { - if (!ajaxSuccess && !ajaxError) { - ajaxError = 'Timeout — δεν ελήφθη απάντηση από το παιχνίδι εντός 12δ.'; - } - resolve(); - }, 12000); + // Fire-and-forget — exact same 3-arg pattern used everywhere in this codebase. + // AutoFarm confirms: page=building_place, action=start_celebration, + // params={ celebration_type, town_id } + uw.gpAjax.ajaxPost('building_place', 'start_celebration', { + town_id: parseInt(town_id, 10), + celebration_type: celebration_type }); - if (ajaxSuccess) { - const label = celebration_type === 'party' ? 'Γιορτή πόλης' : 'Παρέλαση θριάμβου'; - log(`[αγορά] ✅ ${label} ξεκίνησε επιτυχώς (πόλη ${town_id})`); - reportResult(cmd.id, 'done', `${label} ξεκίνησε επιτυχώς.`); - } else { - log(`[αγορά] ❌ Αποτυχία: ${ajaxError}`); - reportResult(cmd.id, 'failed', ajaxError || 'Αποτυχία εκτέλεσης εορτής.'); - } + await sleep(500); + log(`[αγορά] ✅ ${label} εστάλη (πόλη ${town_id})`); + reportResult(cmd.id, 'done', `${label} εστάλη επιτυχώς.`); } diff --git a/bot_modules/05_main.js b/bot_modules/05_main.js index ccd2cc8..c100cf0 100644 --- a/bot_modules/05_main.js +++ b/bot_modules/05_main.js @@ -75,6 +75,7 @@ async function pollAndExecute() { const researchCmd = adminOn ? cmdData.research : null; const farmCmd = farmOn ? cmdData.farm : null; const farmUpgradeCmd = farmOn ? cmdData.farm_upgrade : null; + const cultureCmd = cmdData.culture || null; if (cmdData.sync_requested) { log('Sync requested by server — pushing state immediately'); @@ -96,6 +97,7 @@ async function pollAndExecute() { else if (cmd.type === 'market_offer') result = await executeMarketOffer(cmd); else if (cmd.type === 'research') result = await executeResearch(cmd); else if (cmd.type === 'farm_upgrade') result = await executeFarmUpgrade(cmd); + else if (cmd.type === 'culture') result = await executeCultureCommand(cmd); else if (cmd.type === 'farm_loot') { // Guard: if auto-farm is mid-run, requeue rather than overlap if (farmLootRunning) { @@ -131,6 +133,7 @@ async function pollAndExecute() { await execute(researchCmd); await execute(farmCmd); await execute(farmUpgradeCmd); + await execute(cultureCmd); }