Mj2 : modular and prepare for client options
This commit is contained in:
139
bot_modules/04b_execute_admin.js
Normal file
139
bot_modules/04b_execute_admin.js
Normal file
@@ -0,0 +1,139 @@
|
||||
// ================================================================
|
||||
// 04b_execute_admin.js — Admin command executors
|
||||
// Depends on: uw, log, sleep, randInt, paused
|
||||
// ================================================================
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Execute: Build
|
||||
// ----------------------------------------------------------------
|
||||
async function executeBuild(cmd) {
|
||||
const { town_id, payload } = cmd;
|
||||
const { building_id } = payload;
|
||||
|
||||
const town = uw.ITowns?.getTown?.(town_id) || uw.ITowns?.towns?.[town_id];
|
||||
if (!town) return { ok: false, msg: `Town ${town_id} not found in ITowns` };
|
||||
|
||||
const queueLen = town.buildingOrders?.()?.length ?? 0;
|
||||
const hasCurator = uw.GameDataPremium?.isAdvisorActivated?.('curator');
|
||||
const maxQueue = hasCurator ? 7 : 2;
|
||||
if (queueLen >= maxQueue) {
|
||||
return { ok: false, requeue: true, msg: `Build queue full (${queueLen}/${maxQueue})` };
|
||||
}
|
||||
|
||||
try {
|
||||
const buildData = uw.MM.getModels?.()?.BuildingBuildData?.[town_id]
|
||||
?.attributes?.building_data?.[building_id];
|
||||
if (buildData) {
|
||||
const res = town.resources();
|
||||
const { resources_for, population_for } = buildData;
|
||||
if (town.getAvailablePopulation?.() < population_for) {
|
||||
return { ok: false, requeue: true, msg: `Not enough population for ${building_id}` };
|
||||
}
|
||||
if (res.wood < resources_for.wood || res.stone < resources_for.stone || res.iron < resources_for.iron) {
|
||||
return { ok: false, requeue: true, msg: `Not enough resources for ${building_id}` };
|
||||
}
|
||||
}
|
||||
} catch (e) { log(`Resource check skipped: ${e}`); }
|
||||
|
||||
const reactionMs = randInt(800, 2500);
|
||||
log(`Waiting ${reactionMs}ms before firing buildUp (reaction time)...`);
|
||||
await sleep(reactionMs);
|
||||
|
||||
if (paused) return { ok: false, msg: 'Aborted due to pause/captcha' };
|
||||
|
||||
uw.gpAjax.ajaxPost('frontend_bridge', 'execute', {
|
||||
model_url: 'BuildingOrder',
|
||||
action_name: 'buildUp',
|
||||
arguments: { building_id },
|
||||
town_id
|
||||
});
|
||||
|
||||
await sleep(500);
|
||||
return { ok: true, msg: `buildUp ${building_id} queued` };
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Execute: Recruit
|
||||
// ----------------------------------------------------------------
|
||||
async function executeRecruit(cmd) {
|
||||
const { town_id, payload } = cmd;
|
||||
const { unit_id, amount } = payload;
|
||||
|
||||
const town = uw.ITowns?.getTown?.(town_id) || uw.ITowns?.towns?.[town_id];
|
||||
if (!town) return { ok: false, msg: `Town ${town_id} not found` };
|
||||
|
||||
const navalUnits = [
|
||||
'big_transporter', 'small_transporter', 'bireme',
|
||||
'attack_ship', 'trireme', 'colonize_ship', 'sea_monster'
|
||||
];
|
||||
const endpoint = navalUnits.includes(unit_id) ? 'building_docks' : 'building_barracks';
|
||||
|
||||
const reactionMs = randInt(800, 2500);
|
||||
log(`Waiting ${reactionMs}ms before firing recruit (reaction time)...`);
|
||||
await sleep(reactionMs);
|
||||
|
||||
if (paused) return { ok: false, msg: 'Aborted due to pause/captcha' };
|
||||
|
||||
uw.gpAjax.ajaxPost(endpoint, 'build', {
|
||||
unit_id,
|
||||
amount: parseInt(amount) || 1,
|
||||
town_id
|
||||
});
|
||||
|
||||
await sleep(500);
|
||||
return { ok: true, msg: `Recruit ${amount}x ${unit_id} submitted` };
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Execute: Market Offer
|
||||
// ----------------------------------------------------------------
|
||||
async function executeMarketOffer(cmd) {
|
||||
const { town_id, payload } = cmd;
|
||||
const { offer, offer_type, demand, demand_type, max_delivery_time, visibility } = payload;
|
||||
|
||||
const town = uw.ITowns?.getTown?.(town_id) || uw.ITowns?.towns?.[town_id];
|
||||
if (!town) return { ok: false, msg: `Town ${town_id} not found` };
|
||||
|
||||
const reactionMs = randInt(800, 2500);
|
||||
log(`Waiting ${reactionMs}ms before firing market offer (reaction time)...`);
|
||||
await sleep(reactionMs);
|
||||
|
||||
if (paused) return { ok: false, msg: 'Aborted due to pause/captcha' };
|
||||
|
||||
uw.gpAjax.ajaxPost('frontend_bridge', 'execute', {
|
||||
model_url: 'CreateOffers/' + town_id,
|
||||
action_name: 'createOffer',
|
||||
captcha: null,
|
||||
arguments: { offer, offer_type, demand, demand_type, max_delivery_time, visibility }
|
||||
});
|
||||
|
||||
await sleep(500);
|
||||
return { ok: true, msg: `Market offer posted: ${offer} ${offer_type} => ${demand} ${demand_type}` };
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Execute: Research (Academy)
|
||||
// ----------------------------------------------------------------
|
||||
async function executeResearch(cmd) {
|
||||
const { town_id, payload } = cmd;
|
||||
const { research_id } = payload;
|
||||
|
||||
const town = uw.ITowns?.getTown?.(town_id) || uw.ITowns?.towns?.[town_id];
|
||||
if (!town) return { ok: false, msg: `Town ${town_id} not found` };
|
||||
|
||||
const reactionMs = randInt(800, 2500);
|
||||
log(`Waiting ${reactionMs}ms before firing research (reaction time)...`);
|
||||
await sleep(reactionMs);
|
||||
|
||||
if (paused) return { ok: false, msg: 'Aborted due to pause/captcha' };
|
||||
|
||||
uw.gpAjax.ajaxPost('frontend_bridge', 'execute', {
|
||||
model_url: 'ResearchOrder',
|
||||
action_name: 'research',
|
||||
arguments: { id: research_id },
|
||||
town_id
|
||||
});
|
||||
|
||||
await sleep(500);
|
||||
return { ok: true, msg: `Research ${research_id} queued` };
|
||||
}
|
||||
Reference in New Issue
Block a user