Tickets GM

Sistema de tickets GM

Persistencia, asignación, capa application y networking 4.3.4 / build 15595 para tickets de ayuda estilo WoW. Complementa Comandos GM (comandos . y UI de escritorio gossip).

Objetivos

  • Los jugadores abren tickets desde la UI de ayuda del cliente; el servidor persiste y responde con SMSG_GM_TICKET_*
  • El staff reclama, responde y cierra; los jugadores ven respuestas y pueden resolver (CMSG_GM_TICKET_RESPONSE_RESOLVE)
  • La cola vive en firelands_characters (misma DB que personajes)

Persistencia — tabla gm_ticket

Definida en sql/18_gm_ticket.sql.

ColumnaPropósito
idId estable del ticket
account_idCuenta del jugador
character_guidPersonaje propietario (FK characters.guid)
statusVer GmTicketStatus en domain/models/GmTicket.h
categoryByte de categoría del cliente
messageTexto del jugador
gm_responseÚltima respuesta del staff
map_id, pos_*Snapshot al crear
assigned_account_idGM asignado o NULL en cola abierta
created_at, updated_at, assigned_at, closed_atAuditoría / FIFO

GmTicketStatus

StatusSignificado
OpenEn cola, sin asignar
Assignedassigned_account_id establecido
GmAnsweredRespuesta del staff almacenada
ClosedResolvedJugador resolvió tras respuesta
ClosedAbandonedJugador eliminó ticket
ClosedStaffStaff cerró sin resolución del jugador

Repository

  • Port: domain/repositories/IGmTicketRepository.h
  • Adapter: MySqlGmTicketRepository
  • TryAssign: UPDATE … WHERE assigned_account_id IS NULL AND status = 0 atómico — requiere affected_rows == 1

Reglas de negocio

  1. Un ticket activo por personaje (recomendado) — rechazar tickets abiertos duplicados
  2. Cola: ListUnassignedOpen(N) ordenado por created_at ASC
  3. Reclamar: GmTicketService::Assign(ticketId, staffAccountId) valida permisos, llama TryAssign
  4. Responder: actualizar gm_response, establecer GmAnswered, enviar SMSG_GMRESPONSE_RECEIVED
  5. Cerrar: rutas de resolución staff o jugador actualizan status y timestamps

Capa application

ComponenteRuta
Serviceapplication/services/GmTicketService.*
Handlersinfrastructure/network/sessions/worldsession/WorldSessionGmTicketHandlers.cpp
PacketsGmTicketPackets.cpp
Gossip deskWorldSessionGmTicketGossip.cpp, GmTicketGossipUi.h

Cableado en world/main.cpp: MySqlGmTicketRepositoryGmTicketService → factory WorldSession.

Permiso: ManageGmTickets (por defecto en Game Master).

Opcodes de red (15595)

Constantes en shared/network/WorldOpcodes.h (WowPacketParser V4_3_4_15595/Opcodes.cs).

Cliente → servidor

OpcodeValorRol
CMSG_GM_TICKET_CREATE0x0137Crear ticket
CMSG_GM_TICKET_UPDATE_TEXT0x0636Actualizar mensaje
CMSG_GM_TICKET_DELETE_TICKET0x6B14Eliminar / abandonar
CMSG_GM_TICKET_GET_TICKET0x0326Consultar ticket actual
CMSG_GM_TICKET_GET_SYSTEM_STATUS0x4205Cola habilitada/deshabilitada
CMSG_GM_TICKET_RESPONSE_RESOLVE0x6506Jugador marca resuelto
CMSG_GM_SURVEY_SUBMIT0x2724Encuesta post-resolución

Servidor → cliente

OpcodeValorRol
SMSG_GM_TICKET_CREATE0x2107Resultado de creación
SMSG_GM_TICKET_UPDATE_TEXT0x6535Resultado de actualización
SMSG_GM_TICKET_DELETE_TICKET0x6D17Ack de eliminación
SMSG_GM_TICKET_GET_TICKET0x2C15Payload de ticket o ninguno
SMSG_GM_TICKET_GET_SYSTEM_STATUS0x0D35Habilitar/deshabilitar UI
SMSG_GM_TICKET_STATUS_UPDATE0x2C25Notificación de cola
SMSG_GMRESPONSE_RECEIVED0x2E34Respuesta GM al jugador
SMSG_GMRESPONSE_STATUS_UPDATE0x0A04Tras resolver
SMSG_GMRESPONSE_DB_ERROR0x0006Error de backend

Importante: No copies layouts de la era 3.3.5. Usa structs WowPacketParser 15595 o capturas sniff; prueba unitaria blobs hex fijos bajo tests/data/.

UI de staff

.ticket ui abre un escritorio gossip sintético (sin NPC). Ids de menú/texto reservados evitan colisionar con gossip de world DB. UX completa documentada en Comandos GM.

Estado de implementación

  • MySqlGmTicketRepository, GmTicketService, ruta CMSG/SMSG core
  • Comandos .ticket en juego y UI de escritorio gossip
  • Sanitización de hipervínculos de referencia (endurecimiento opcional)

Relacionado