fix 2
This commit is contained in:
@@ -6,14 +6,17 @@
|
|||||||
// 'party' → Γιορτή πόλης (costs wood/stone/iron)
|
// 'party' → Γιορτή πόλης (costs wood/stone/iron)
|
||||||
// 'triumph' → Παρέλαση θριάμβου (costs battle points)
|
// 'triumph' → Παρέλαση θριάμβου (costs battle points)
|
||||||
//
|
//
|
||||||
// On success/failure, reports back to /api/commands/<id>/result
|
// Uses the same fire-and-forget ajaxPost pattern as all other
|
||||||
// so the culture_log row is updated from 'pending' to 'success'/'failed'.
|
// execute modules in this codebase (04a, 04b, 04c).
|
||||||
// ================================================================
|
// ================================================================
|
||||||
|
|
||||||
async function executeCultureCommand(cmd) {
|
async function executeCultureCommand(cmd) {
|
||||||
if (!cmd || !cmd.id || !cmd.payload) return;
|
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) {
|
if (!celebration_type || !town_id) {
|
||||||
reportResult(cmd.id, 'failed', 'Invalid culture payload: missing celebration_type or town_id');
|
reportResult(cmd.id, 'failed', 'Invalid culture payload: missing celebration_type or town_id');
|
||||||
return;
|
return;
|
||||||
@@ -24,9 +27,10 @@ async function executeCultureCommand(cmd) {
|
|||||||
return;
|
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];
|
const town = uw.ITowns?.towns?.[town_id];
|
||||||
if (!town) {
|
if (!town) {
|
||||||
reportResult(cmd.id, 'failed', `Η πόλη ${town_id} δεν βρέθηκε στη μνήμη του παιχνιδιού.`);
|
reportResult(cmd.id, 'failed', `Η πόλη ${town_id} δεν βρέθηκε στη μνήμη του παιχνιδιού.`);
|
||||||
@@ -44,58 +48,32 @@ async function executeCultureCommand(cmd) {
|
|||||||
&& a.celebration_type === celebration_type
|
&& a.celebration_type === celebration_type
|
||||||
&& (a.finished_at ?? 0) > nowTs) {
|
&& (a.finished_at ?? 0) > nowTs) {
|
||||||
reportResult(cmd.id, 'failed',
|
reportResult(cmd.id, 'failed',
|
||||||
`${celebration_type === 'party' ? 'Γιορτή' : 'Παρέλαση'} ήδη ενεργή στην πόλη ${town_id}.`);
|
`${label} ήδη ενεργή στην πόλη ${town_id}.`);
|
||||||
return;
|
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
|
// Human-like reaction delay — same as all other executors
|
||||||
let ajaxSuccess = false;
|
const reactionMs = randInt(800, 2500);
|
||||||
let ajaxError = null;
|
log(`[αγορά] Waiting ${reactionMs}ms (reaction time)...`);
|
||||||
|
await sleep(reactionMs);
|
||||||
|
|
||||||
await new Promise(resolve => {
|
if (paused) {
|
||||||
try {
|
reportResult(cmd.id, 'failed', 'Aborted due to pause/captcha');
|
||||||
uw.gpAjax.ajaxPost(
|
return;
|
||||||
'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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Safety timeout: if neither callback fires within 12 s, treat as failed
|
// Fire-and-forget — exact same 3-arg pattern used everywhere in this codebase.
|
||||||
setTimeout(() => {
|
// AutoFarm confirms: page=building_place, action=start_celebration,
|
||||||
if (!ajaxSuccess && !ajaxError) {
|
// params={ celebration_type, town_id }
|
||||||
ajaxError = 'Timeout — δεν ελήφθη απάντηση από το παιχνίδι εντός 12δ.';
|
uw.gpAjax.ajaxPost('building_place', 'start_celebration', {
|
||||||
}
|
town_id: parseInt(town_id, 10),
|
||||||
resolve();
|
celebration_type: celebration_type
|
||||||
}, 12000);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ajaxSuccess) {
|
await sleep(500);
|
||||||
const label = celebration_type === 'party' ? 'Γιορτή πόλης' : 'Παρέλαση θριάμβου';
|
log(`[αγορά] ✅ ${label} εστάλη (πόλη ${town_id})`);
|
||||||
log(`[αγορά] ✅ ${label} ξεκίνησε επιτυχώς (πόλη ${town_id})`);
|
reportResult(cmd.id, 'done', `${label} εστάλη επιτυχώς.`);
|
||||||
reportResult(cmd.id, 'done', `${label} ξεκίνησε επιτυχώς.`);
|
|
||||||
} else {
|
|
||||||
log(`[αγορά] ❌ Αποτυχία: ${ajaxError}`);
|
|
||||||
reportResult(cmd.id, 'failed', ajaxError || 'Αποτυχία εκτέλεσης εορτής.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ async function pollAndExecute() {
|
|||||||
const researchCmd = adminOn ? cmdData.research : null;
|
const researchCmd = adminOn ? cmdData.research : null;
|
||||||
const farmCmd = farmOn ? cmdData.farm : null;
|
const farmCmd = farmOn ? cmdData.farm : null;
|
||||||
const farmUpgradeCmd = farmOn ? cmdData.farm_upgrade : null;
|
const farmUpgradeCmd = farmOn ? cmdData.farm_upgrade : null;
|
||||||
|
const cultureCmd = cmdData.culture || null;
|
||||||
|
|
||||||
if (cmdData.sync_requested) {
|
if (cmdData.sync_requested) {
|
||||||
log('Sync requested by server — pushing state immediately');
|
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 === 'market_offer') result = await executeMarketOffer(cmd);
|
||||||
else if (cmd.type === 'research') result = await executeResearch(cmd);
|
else if (cmd.type === 'research') result = await executeResearch(cmd);
|
||||||
else if (cmd.type === 'farm_upgrade') result = await executeFarmUpgrade(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') {
|
else if (cmd.type === 'farm_loot') {
|
||||||
// Guard: if auto-farm is mid-run, requeue rather than overlap
|
// Guard: if auto-farm is mid-run, requeue rather than overlap
|
||||||
if (farmLootRunning) {
|
if (farmLootRunning) {
|
||||||
@@ -131,6 +133,7 @@ async function pollAndExecute() {
|
|||||||
await execute(researchCmd);
|
await execute(researchCmd);
|
||||||
await execute(farmCmd);
|
await execute(farmCmd);
|
||||||
await execute(farmUpgradeCmd);
|
await execute(farmUpgradeCmd);
|
||||||
|
await execute(cultureCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user