eaae16e33a
- /change-race-character (3€), /change-faction-character (5€, valida condiciones: sin hermandad/correo/subastas/capitán-arena y oro <= cap por nivel), /level-up-character (10€), /gold-character (oro por correo SOAP). Cada uno borra su ruta antigua y actualiza el link del panel. - SumUp: hook precheck en PaidServiceConfig (condiciones cambio de facción); columna home_stripelog.metadata para campos extra (gold_amount). - /quest-character: rastreador de estado de misiones/cadenas (clase, Hijos de Hodir, misión por ID) en personaje offline; cooldowns por categoría, Turnstile, IDs de misión verificados en wotlkdb 3.3.5a. Tabla home_questsearchhistory. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
import type { RowDataPacket } from 'mysql2'
|
|
import { db, DB } from './db'
|
|
|
|
/**
|
|
* Condiciones para cambiar de facción (AzerothCore). El personaje NO puede:
|
|
* tener subastas activas, correos en el buzón, ser capitán de un equipo de arena,
|
|
* ser miembro de una hermandad, ni superar el máximo de oro según su nivel.
|
|
*/
|
|
|
|
/** Máximo de oro (en oro) permitido según el nivel. */
|
|
export function factionGoldCap(level: number): number {
|
|
if (level <= 30) return 300
|
|
if (level <= 50) return 1000
|
|
if (level <= 70) return 5000
|
|
return 20000
|
|
}
|
|
|
|
export interface FactionEligibility {
|
|
ok: boolean
|
|
reasons: string[]
|
|
}
|
|
|
|
export async function checkFactionChangeEligibility(accountId: number, character: string): Promise<FactionEligibility> {
|
|
const [chars] = await db(DB.characters).query<RowDataPacket[]>(
|
|
'SELECT guid, level, money FROM characters WHERE name = ? AND account = ? LIMIT 1',
|
|
[character, accountId],
|
|
)
|
|
const ch = chars[0]
|
|
if (!ch) return { ok: false, reasons: ['El personaje no pertenece a tu cuenta.'] }
|
|
|
|
const guid = Number(ch.guid)
|
|
const level = Number(ch.level)
|
|
const money = Number(ch.money)
|
|
const reasons: string[] = []
|
|
|
|
const cap = factionGoldCap(level)
|
|
if (money > cap * 10000) reasons.push(`tiene demasiado oro (máximo ${cap} para su nivel)`)
|
|
|
|
// Cada condición en su try/catch: alguna tabla puede no existir en esta BD.
|
|
const exists = async (sql: string): Promise<boolean> => {
|
|
try {
|
|
const [rows] = await db(DB.characters).query<RowDataPacket[]>(sql, [guid])
|
|
return Boolean(rows[0])
|
|
} catch {
|
|
return false // tabla ausente => no bloquea (el core lo valida al aplicar)
|
|
}
|
|
}
|
|
|
|
if (await exists('SELECT 1 FROM guild_member WHERE guid = ? LIMIT 1')) reasons.push('es miembro de una hermandad')
|
|
if (await exists('SELECT 1 FROM mail WHERE receiver = ? LIMIT 1')) reasons.push('tiene correos en el buzón')
|
|
if (await exists('SELECT 1 FROM auctionhouse WHERE owner = ? LIMIT 1')) reasons.push('tiene subastas activas')
|
|
if (await exists('SELECT 1 FROM arena_team WHERE captainGuid = ? LIMIT 1')) reasons.push('es capitán de un equipo de arena')
|
|
|
|
return { ok: reasons.length === 0, reasons }
|
|
}
|