Cliente SOAP + servicios de personaje SOAP (revive/unstuck) en Next.js

- lib/soap.ts: executeSoapCommand (port de ac_soap.py; POST SOAP + basic auth al
  worldserver, timeout 5s, null si inaccesible). AC_SOAP_* en .env.local.
- lib/characters.ts: getGameCharacters / characterIsOfflineAndOwned (acore_characters).
- lib/character-services.ts: soapCharacterAction genérico (valida propiedad+offline,
  cooldown 12h vía home_revive/unstuckhistory, SOAP, registra historial) ->
  reviveCharacter / unstuckCharacter.
- components/CharacterActionForm.tsx (cliente reutilizable: select + botón).
- Routes /api/character/revive|unstuck (guard de sesión) y páginas
  app/[locale]/revive|unstuck (SSR, guardas, i18n). Namespace Services.

Verificado: API sin sesión 401, páginas redirigen a login, cliente SOAP devuelve null
limpio sin worldserver. Patrón base para el resto de servicios de personaje.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 23:16:32 +00:00
parent a0a64bc70a
commit 96e996e9c2
10 changed files with 305 additions and 0 deletions
+15
View File
@@ -120,5 +120,20 @@
"passwordTooLong": "La contraseña no debe exceder los 16 caracteres.",
"accountNotFound": "No se ha encontrado la cuenta.",
"genericError": "Algo ha salido mal. Inténtalo más tarde."
},
"Services": {
"reviveTitle": "Revivir personaje",
"unstuckTitle": "Desbloquear personaje",
"reviveAction": "Revivir",
"unstuckAction": "Desbloquear",
"selectCharacter": "Selecciona un personaje",
"noCharactersYet": "No tienes personajes disponibles.",
"processing": "Procesando…",
"success": "Acción realizada con éxito.",
"noCharacter": "Selecciona un personaje.",
"notOfflineOrOwned": "El personaje debe estar desconectado y ser tuyo.",
"cooldown": "Solo puedes hacerlo una vez cada 12 horas.",
"soapError": "Error de comunicación con el servidor. Inténtalo más tarde.",
"genericError": "Algo ha salido mal. Inténtalo más tarde."
}
}