import type { RowDataPacket } from 'mysql2' import { db, DB } from './db' import { executeSoapCommand } from './soap' import { characterIsOfflineAndOwned } from './characters' export interface Result { success: boolean error?: string } interface SoapActionConfig { command: (character: string) => string historyTable: string // tabla django_wow con columnas (character_name, used_at) cooldownHours: number } /** Acción de personaje por SOAP con cooldown (revive, unstuck...). */ async function soapCharacterAction(accountId: number, character: string, cfg: SoapActionConfig): Promise { if (!character) return { success: false, error: 'noCharacter' } if (!(await characterIsOfflineAndOwned(accountId, character))) { return { success: false, error: 'notOfflineOrOwned' } } try { const [rows] = await db(DB.default).query( `SELECT used_at FROM ${cfg.historyTable} WHERE character_name = ? ORDER BY used_at DESC LIMIT 1`, [character], ) if (rows[0] && Date.now() - new Date(rows[0].used_at).getTime() < cfg.cooldownHours * 3600_000) { return { success: false, error: 'cooldown' } } } catch { /* tabla de historial ausente: seguimos */ } const resp = await executeSoapCommand(cfg.command(character)) if (resp === null) return { success: false, error: 'soapError' } await db(DB.default).query( `INSERT INTO ${cfg.historyTable} (character_name, used_at) VALUES (?, NOW())`, [character], ) return { success: true } } export function reviveCharacter(accountId: number, character: string): Promise { return soapCharacterAction(accountId, character, { command: (c) => `.revive ${c}`, historyTable: 'home_revivehistory', cooldownHours: 12, }) } export function unstuckCharacter(accountId: number, character: string): Promise { return soapCharacterAction(accountId, character, { command: (c) => `.unstuck ${c}`, historyTable: 'home_unstuckhistory', cooldownHours: 12, }) }