DRS Tickets

v2.4.0 drs_tickets
Ver na loja

Sistema de tickets de suporte dentro do jogo. O jogador abre um ticket por categoria e fala com o staff em tempo real. O staff tem um painel para assumir, responder, mudar o estado e a prioridade, deixar notas internas e ir ter com o jogador. No fim, o jogador avalia o atendimento, e o dono do servidor vê as estatísticas da equipa. Funciona com Qbox, QBCore, ESX ou sem framework.

#Requisitos

RecursoObrigatório
oxmysqlSim
Qbox, QBCore, ESX ou nenhumSim (deteção automática; 'none' funciona sem framework)
ox_libNão — só para as notificações do ox

#Instalação

  1. Coloca drs_tickets em resources.
  2. Adiciona ao server.cfg, depois do oxmysql e da framework:
server.cfg
ensure oxmysql
ensure qb-core
ensure drs_tickets
  1. As tabelas drs_tickets e drs_ticket_messages são criadas sozinhas no primeiro arranque.
  2. Dá acesso ao staff e ao dono do servidor:
server.cfg
# staff: vê e responde aos tickets
add_ace group.admin drs.tickets allow
# dono: vê também a aba Estatísticas
add_ace group.god drs.tickets.owner allow

Também conta como staff quem tiver um grupo de Config.StaffGroups (QBCore/Qbox: permissões; ESX: grupo). O dono também pode ser definido pelos identificadores em Config.OwnerIdentifiers.

#Comandos

ComandoQuemO que faz
/reportTodosAbre os tickets: criar um novo, ver os teus e o histórico
/ticketsStaffAbre direto no painel do staff

Com Config.OpenKey (ex.: 'F10') também abre com uma tecla. Os nomes dos comandos estão em Config.Command e Config.StaffCommand.

#Para o jogador

  1. /report → Novo ticket.
  2. Escolhe a categoria (Config.Categories: Dúvida, Denúncia, Bug, Reembolso, Outro), escreve o assunto e a mensagem.
  3. Opcionalmente junta o link de um clip (Config.Clips, ex.: medal.tv). Com required = true, o clip é obrigatório.
  4. Enquanto espera, uma barra no topo do ecrã mostra a posição na fila, o tempo e o estado (Config.QueueBar).
  5. As respostas do staff aparecem em tempo real. Se sair do servidor, é avisado das respostas por ler quando voltar.
  6. Quando o ticket fecha, avalia o atendimento de 1 a 5 estrelas (Config.Ratings).

Cada jogador pode ter até Config.MaxOpenPerPlayer tickets abertos ao mesmo tempo.

#Para o staff

  • Aviso de ticket novo, com som (Config.AlertStaff, Config.AlertSound).
  • Assumir o ticket (fica com o teu nome).
  • Estado: aberto, em curso, fechado. Prioridade: normal, alta, urgente.
  • Notas internas que só o staff vê.
  • Respostas rápidas (Config.QuickReplies) com um clique.
  • Ir até ao jogador ou trazê-lo (Config.StaffActions).
  • Separador Equipa com o ranking do staff pelas avaliações.

O dono do servidor vê ainda a aba Estatísticas (jogadores e staff).

Tickets sem respostas há Config.AutoCloseHours horas fecham sozinhos (0 = nunca).

#Categorias

config.lua
Config.Categories = {
    { id = 'help',   label = 'Dúvida',   color = '#60a5fa', icon = 'help' },
    { id = 'report', label = 'Denúncia', color = '#f87171', icon = 'shield' },
    { id = 'vip',    label = 'VIP',      color = '#facc15', icon = 'money' },
}

O id tem de ser único. Ícones disponíveis: help, bug, shield, user, car, money e chat.

#Opções principais

OpçãoPor defeitoDescrição
Config.Locale'pt'Idioma: pt ou en
Config.Command'report'Comando dos jogadores
Config.StaffCommand'tickets'Comando do staff
Config.OpenKey''Tecla para abrir
Config.StaffGroupsgod, admin, superadmin, modGrupos que contam como staff
Config.MaxOpenPerPlayer2Tickets abertos por jogador
Config.CreateCooldown60Segundos entre tickets novos
Config.MessageMax1000Tamanho máximo de cada mensagem
Config.AutoCloseHours48Fecho automático (0 = nunca)
Config.QueueBartrueBarra da fila no topo do ecrã
Config.RatingstrueAvaliação no fim
Config.Webhook''Webhook do Discord

#Configuração completa

config.lua
Config = {}

-- Idioma / Language: 'pt' ou 'en'
Config.Locale = 'pt'

-- Framework: 'auto' deteta Qbox/QBCore/ESX (ou 'qbx' | 'qb' | 'esx' | 'none')
Config.Framework = 'auto'

-- Comandos / Commands
Config.Command = 'report'          -- abrir os tickets (jogadores e staff) / open tickets (players and staff)
Config.StaffCommand = 'tickets'    -- abrir direto no painel do staff / open straight in the staff panel
-- Tecla para abrir (vazio = sem tecla) / Key to open (empty = no key)
Config.OpenKey = ''

-- ------------------------------------------------------------------ staff
-- Quem é staff: ACE 'drs.tickets' OU um destes grupos (QBCore/Qbox: permissões, ESX: grupo)
-- Who is staff: ACE 'drs.tickets' OR one of these groups (QBCore/Qbox: permissions, ESX: group)
Config.StaffGroups = { 'god', 'admin', 'superadmin', 'mod' }

-- Dono do servidor: vê a aba Estatísticas (jogadores e staff). ACE ou identificadores.
-- Server owner: sees the Statistics tab (players and staff). ACE or identifiers.
--   server.cfg:  add_ace qbcore.god drs.tickets.owner allow
Config.OwnerAce = 'drs.tickets.owner'
Config.OwnerIdentifiers = {
    -- 'license:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
}

-- Ações rápidas do staff no ticket / Staff quick actions on a ticket
Config.StaffActions = {
    go = true,        -- ir até ao jogador / teleport to the player
    bring = true,     -- trazer o jogador / bring the player
}

-- Avisar o staff online quando entra um ticket novo (com som) / Alert online staff on new tickets (with sound)
Config.AlertStaff = true
Config.AlertSound = true

-- ------------------------------------------------------------------ limites / limits
Config.MaxOpenPerPlayer = 2       -- tickets abertos ao mesmo tempo por jogador / open tickets per player at once
Config.CreateCooldown = 60        -- segundos entre tickets novos / seconds between new tickets
Config.MessageCooldown = 2        -- segundos entre mensagens / seconds between messages
Config.SubjectMax = 80            -- tamanho máximo do assunto / max subject length
Config.MessageMax = 1000          -- tamanho máximo de cada mensagem / max message length
Config.HistoryLimit = 30          -- tickets fechados que o jogador vê no histórico / closed tickets shown in history

-- Fechar sozinho tickets sem respostas há X horas (0 = nunca) / Auto-close tickets idle for X hours (0 = never)
Config.AutoCloseHours = 48

-- Link de um clip ao abrir o ticket (opcional) / Clip link when opening a ticket (optional)
Config.Clips = {
    enabled = true,
    required = false,
    domains = { 'medal.tv' },    -- ex.: { 'medal.tv', 'youtube.com', 'youtu.be', 'streamable.com' }
}

-- Barra no topo do ecrã para quem está à espera: posição na fila, tempo e estado
-- Top bar for players waiting: queue position, time and state
Config.QueueBar = true

-- Avaliação do atendimento depois de fechado / Rate the support after it is closed
Config.Ratings = true

-- ------------------------------------------------------------------ categorias / categories
-- id: único; label: nome; color: cor; icon: 'help' | 'bug' | 'shield' | 'user' | 'car' | 'money' | 'chat'
Config.Categories = {
    { id = 'help',    label = 'Dúvida',          color = '#60a5fa', icon = 'help' },
    { id = 'report',  label = 'Denúncia',        color = '#f87171', icon = 'shield' },
    { id = 'bug',     label = 'Bug',             color = '#fbbf24', icon = 'bug' },
    { id = 'refund',  label = 'Reembolso',       color = '#4ade80', icon = 'money' },
    { id = 'other',   label = 'Outro',           color = '#c084fc', icon = 'chat' },
}

-- Respostas rápidas do staff / Staff quick replies
Config.QuickReplies = {
    'Olá! Já estou a ver o teu ticket, dá-me só um momento.',
    'Consegues dar-me mais detalhes (hora, local e quem estava envolvido)?',
    'Vou ter contigo agora.',
    'O teu problema ficou resolvido. Se precisares de mais alguma coisa, abre um ticket novo.',
}

-- ------------------------------------------------------------------ logs
-- Webhook do Discord (vazio = desligado) / Discord webhook (empty = off)
Config.Webhook = ''

-- Notificações com ox_lib quando estiver a correr / Use ox_lib notifications when it is running
Config.UseOxNotify = false

#Para programadores

server
exports.drs_tickets:GetOpenCount()   -- número de tickets por fechar

Útil, por exemplo, para mostrar no HUD do staff quantos tickets estão à espera.

#Segurança

Tudo é validado no servidor: dono do ticket, permissões de staff e tamanhos. Há limite de tickets abertos, tempo de espera entre tickets e entre mensagens, e limite de pedidos por jogador. O texto é limpo no servidor e escapado na interface, por isso ninguém consegue meter código nas mensagens.

#Resolução de problemas

O /tickets diz que não tens permissão — falta a ACE drs.tickets ou um grupo de Config.StaffGroups. Depois de mudares o server.cfg, reinicia o servidor.

Não aparece a aba Estatísticas — é só para o dono: ACE drs.tickets.owner ou identificador em Config.OwnerIdentifiers.

"Espera X s antes de abrir outro ticket" / "Estás a escrever depressa demais" — há um tempo de espera entre tickets (CreateCooldown) e entre mensagens (MessageCooldown).

"Já tens X tickets abertos" — o jogador chegou ao limite de Config.MaxOpenPerPlayer; tem de esperar que um seja fechado.

O link do clip é recusado — só são aceites os domínios de Config.Clips.domains.