fix for buildinds
This commit is contained in:
@@ -833,8 +833,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Build queue, Recruit queue and Market queue are independent
|
||||
const buildCmd = cmdData.build;
|
||||
// Build queue: one command per town (all towns build in the same poll cycle)
|
||||
const buildCmds = cmdData.builds || [];
|
||||
const recruitCmd = cmdData.recruit;
|
||||
const marketCmd = cmdData.market;
|
||||
const researchCmd = cmdData.research;
|
||||
@@ -873,8 +873,16 @@
|
||||
reportResult(cmd.id, finalStatus, result.msg);
|
||||
};
|
||||
|
||||
// Run sequentially — humans cannot perform 3 actions simultaneously!
|
||||
await execute(buildCmd);
|
||||
// Execute ALL town build commands (one per town, sequential with inter-town delay)
|
||||
for (let i = 0; i < buildCmds.length; i++) {
|
||||
await execute(buildCmds[i]);
|
||||
if (i < buildCmds.length - 1) {
|
||||
// Random gap between towns so it doesn't look like a macro
|
||||
const gap = randInt(1500, 3000);
|
||||
log(`Build: town done. Waiting ${gap}ms before next town...`);
|
||||
await sleep(gap);
|
||||
}
|
||||
}
|
||||
await execute(recruitCmd);
|
||||
await execute(marketCmd);
|
||||
await execute(researchCmd);
|
||||
|
||||
@@ -22,7 +22,8 @@ async function pollAndExecute() {
|
||||
const farmOn = features.includes('farm');
|
||||
const adminOn = features.includes('admin');
|
||||
|
||||
const buildCmd = adminOn ? cmdData.build : null;
|
||||
// Build: one command per town (server returns an array)
|
||||
const buildCmds = adminOn ? (cmdData.builds || []) : [];
|
||||
const recruitCmd = adminOn ? cmdData.recruit : null;
|
||||
const marketCmd = adminOn ? cmdData.market : null;
|
||||
const researchCmd = adminOn ? cmdData.research : null;
|
||||
@@ -60,8 +61,16 @@ async function pollAndExecute() {
|
||||
reportResult(cmd.id, finalStatus, result.msg);
|
||||
};
|
||||
|
||||
// Run sequentially — humans cannot perform 3 actions simultaneously!
|
||||
await execute(buildCmd);
|
||||
// Execute one build command per town (simultaneous queue draining across all villages)
|
||||
for (let i = 0; i < buildCmds.length; i++) {
|
||||
await execute(buildCmds[i]);
|
||||
if (i < buildCmds.length - 1) {
|
||||
// Random inter-town gap — avoids looking like a macro
|
||||
const gap = randInt(1500, 3000);
|
||||
log(`Build: town done. Waiting ${gap}ms before next town...`);
|
||||
await sleep(gap);
|
||||
}
|
||||
}
|
||||
await execute(recruitCmd);
|
||||
await execute(marketCmd);
|
||||
await execute(researchCmd);
|
||||
|
||||
@@ -105,10 +105,11 @@ def receive_state():
|
||||
# so both queues are served in parallel without blocking each other.
|
||||
# ------------------------------------------------------------------
|
||||
def _fetch_pending_of_type(c, cmd_type, player_id):
|
||||
"""Fetch a single oldest pending command of a given type (recruit, market, etc.)."""
|
||||
row = c.execute('''
|
||||
SELECT * FROM commands
|
||||
WHERE status = 'pending' AND type = ? AND player_id = ?
|
||||
ORDER BY id ASC
|
||||
ORDER BY updated_at ASC, id ASC
|
||||
LIMIT 1
|
||||
''', (cmd_type, player_id)).fetchone()
|
||||
if not row:
|
||||
@@ -125,6 +126,49 @@ def _fetch_pending_of_type(c, cmd_type, player_id):
|
||||
'payload': json.loads(row['payload'])
|
||||
}
|
||||
|
||||
|
||||
def _fetch_pending_builds_all_towns(c, player_id):
|
||||
"""
|
||||
Fetch ONE pending 'build' command per distinct town_id.
|
||||
This allows all towns to build in parallel within a single poll cycle.
|
||||
Within each town the oldest-updated command is picked first, so requeued
|
||||
commands (updated_at = now) naturally sort behind fresh ones.
|
||||
"""
|
||||
# Get every town that has at least one pending build, ordered by
|
||||
# which town has been waiting longest (MIN updated_at across its commands).
|
||||
town_rows = c.execute('''
|
||||
SELECT town_id
|
||||
FROM commands
|
||||
WHERE status = 'pending' AND type = 'build' AND player_id = ?
|
||||
GROUP BY town_id
|
||||
ORDER BY MIN(updated_at) ASC
|
||||
''', (player_id,)).fetchall()
|
||||
|
||||
results = []
|
||||
now = datetime.utcnow().isoformat()
|
||||
for town_row in town_rows:
|
||||
town_id = town_row['town_id']
|
||||
row = c.execute('''
|
||||
SELECT * FROM commands
|
||||
WHERE status = 'pending' AND type = 'build'
|
||||
AND player_id = ? AND town_id = ?
|
||||
ORDER BY updated_at ASC, id ASC
|
||||
LIMIT 1
|
||||
''', (player_id, town_id)).fetchone()
|
||||
if not row:
|
||||
continue
|
||||
c.execute('''
|
||||
UPDATE commands SET status = 'executing', updated_at = ?
|
||||
WHERE id = ?
|
||||
''', (now, row['id']))
|
||||
results.append({
|
||||
'id': row['id'],
|
||||
'town_id': row['town_id'],
|
||||
'type': row['type'],
|
||||
'payload': json.loads(row['payload'])
|
||||
})
|
||||
return results
|
||||
|
||||
@api.route('/api/commands/pending', methods=['GET'])
|
||||
def get_pending_command():
|
||||
player_id = request.args.get('player_id')
|
||||
@@ -134,7 +178,7 @@ def get_pending_command():
|
||||
conn = get_db()
|
||||
c = conn.cursor()
|
||||
|
||||
build_cmd = _fetch_pending_of_type(c, 'build', player_id)
|
||||
build_cmds = _fetch_pending_builds_all_towns(c, player_id) # one per town
|
||||
recruit_cmd = _fetch_pending_of_type(c, 'recruit', player_id)
|
||||
market_cmd = _fetch_pending_of_type(c, 'market_offer', player_id)
|
||||
farm_cmd = _fetch_pending_of_type(c, 'farm_loot', player_id)
|
||||
@@ -164,7 +208,7 @@ def get_pending_command():
|
||||
conn.close()
|
||||
|
||||
return jsonify({
|
||||
'build': build_cmd,
|
||||
'builds': build_cmds, # list: one build command per town
|
||||
'recruit': recruit_cmd,
|
||||
'market': market_cmd,
|
||||
'research': research_cmd,
|
||||
|
||||
Reference in New Issue
Block a user