Criador de jobs e gangs em jogo: cria os grupos no qbx_core, define cargos e salários, e coloca no mundo os pontos de bater ponto, cofre, alarme, boss menu, bancadas de crafting e lojas — tudo sem editar arquivo nem reiniciar o servidor.
A tabela é criada automaticamente no start do recurso:
CREATE TABLE IF NOT EXISTS `mri_qjobsystem` ( `jobs` longtext) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
Na primeira execução, se a tabela estiver vazia, o conteúdo de server/jobs.json é carregado e gravado no banco. A partir daí o banco é a fonte da verdade — o jobs.json só serve como seed inicial.
Conflito com os jobs do qbx_core — os grupos criados aqui são registrados em runtime por cima dos definidos em qbx_core/shared/jobs.lua e gangs.lua. Um grupo com o mesmo nome nos dois lugares será sobrescrito pelo deste recurso a cada start.
O gate real está no lib.addCommand (restricted = 'group.admin'). Do lado do servidor, os eventos de escrita passam por CanTrustPlayer (anti-trigger externo) e por IsPlayerHasCustomPerms, que na versão atual sempre retorna true — é o ponto de extensão previsto pelo autor caso você queira uma checagem de permissão própria além do ACE do comando.
Esqueleto de um grupo novo. Não precisa ser alterado
Config.DEFAULT_ANIM
string
Sim
Animação usada no crafting quando o item não define uma própria. Padrão: hack_loop
Config.DEFAULT_ANIM_DIC
string
Sim
Dicionário da animação padrão. Padrão: mp_prison_break
Config.BlacklistedStrings
lista de strings
Sim
Trechos proibidos nos nomes digitados no criador (armas, drogas, dinheiro...). Vem vazio por padrão — a lista sugerida está comentada no arquivo
Config.jobTypeList
lista
Sim
Tipos de job oferecidos no criador (leo, ems, mechanic, realestate, sem tipo). O tipo alimenta o job.type do qbx_core, usado por outros recursos (dispatch, HUD, etc.)
Config.DirectoryToInventoryImages
string
Sim
Caminho NUI das imagens dos itens. Padrão: nui://ox_inventory/web/images/
O config.lua também define, no client, as funções openBossmenu (chama exports.qbx_management:OpenBossMenu) e SendDispatch (chama exports["ps-dispatch"]:CustomAlert para a job police). É aí que se troca o recurso de dispatch ou a lista de jobs alertadas.
Código do grupo — identificador interno, sempre minúsculo (ex.: police). Se já existir um job com esse código no qbx_core, a criação é recusada.
Tipo — Job (com salário e ponto) ou Gang (sem salário e sem ponto).
Quantidade de cargos.
Para jobs: o tipo de trabalho (leo, ems, mechanic, realestate ou sem tipo).
Um formulário por cargo, do índice 0 até n-1, com nome e — no caso de job — salário.
O último cargo criado recebe automaticamente isboss e bankAuth. As coordenadas do personagem no momento da criação são salvas como coords do grupo. Ao final, o menu de gerenciamento abre.
/open_jobs lista todos os grupos. Ao escolher um, as opções são:
Opção
O que faz
Renomear
Altera o label do grupo
Cargos
Gerencia hierarquia, nomes e salários
Local para Bater Ponto
Define/remove o ponto de duty na posição da mira
Ponto batido por padrão
Liga/desliga defaultDuty (entra em serviço automaticamente ao logar)
Caixa registradora
Define/remove o ponto do cofre do grupo
Alarme
Define/remove o ponto de alarme (aciona o dispatch)
Bossmenu
Define/remove o ponto do boss menu
Craftings/Lojas
Abre o submenu de bancadas e lojas
Excluir grupo
Remove o grupo
Atualizar para MIM
Recarrega os pontos apenas para quem está no menu
Atualizar para TODOS
Recarrega os pontos para todos os jogadores online
Backup
Cria ou restaura o server/backup.json
As posições dos pontos são capturadas por raycast (onde você está mirando), não pela posição do personagem.
Depois de qualquer alteração, use Atualizar para TODOS para os pontos aparecerem para quem já está conectado — os dados são salvos na hora, mas os targets no mundo só são recriados no pull.
Um item de craftings vira uma bancada ou uma loja, dependendo do ícone escolhido:
Ícone fa-solid fa-screwdriver-wrench (padrão) — bancada de crafting: abre um menu com as receitas, mostra os ingredientes necessários, pede a quantidade, roda a barra de progresso com animação e consome os itens no servidor.
Qualquer outro ícone — loja: abre o ox_inventory no modo shop. A loja é registrada no start via exports.ox_inventory:RegisterShop, usando o primeiro ingrediente do item como moeda e preço.
Cada bancada/loja pode ser marcada como public — nesse caso qualquer jogador pode usar. Caso contrário, só quem estiver na job ou gang dona do ponto.
Cada item de crafting aceita duration (segundos por unidade), animation (dict/anim, ou scully para usar um emote via /e), stockAmount, license, grade e metadata.
O ponto "Caixa registradora" abre um menu com o saldo do grupo e as opções de retirar e depositar. O saldo fica no campo balance do grupo e é validado no servidor: não é possível sacar mais do que há no cofre nem depositar mais dinheiro do que o jogador tem.
Só quem está na job ou gang dona do ponto consegue abrir.
Com o qbx_management instalado, o recurso adiciona um item "Gerenciar Permissões" no boss menu de jobs e de gangs (AddBossMenuItem / AddGangMenuItem). Ele abre um menu onde se alternam as flags de cada cargo (isboss, bankAuth, isrecruiter).
Ao mudar uma flag, o servidor grava a alteração e reaplica o grupo a todos os personagens naquele cargo (consultando player_groups e chamando SetPlayerPrimaryJob / SetPlayerPrimaryGang), para que a permissão passe a valer sem precisar relogar. A flag isboss do cargo mais alto é bloqueada — não dá para remover o líder.
Todos os grupos ficam em uma única linha da tabela mri_qjobsystem, na coluna jobs (JSON).
server/jobs.json é apenas o seed usado quando a tabela está vazia.
Backup grava o estado atual em server/backup.json (sobrescrevendo o anterior). Restaurar lê esse arquivo e o grava de volta no banco. Confira se o backup.json não está vazio antes de restaurar.
Os eventos de escrita não são disparados com TriggerServerEvent direto: o client usa TriggerSecureEvent, que primeiro registra um token temporário no servidor (secure.lua). No servidor, cada handler chama CanTrustPlayer(src), que só aceita a chamada se o token tiver sido gerado há menos de 1 segundo. Isso bloqueia eventos disparados por executores externos.
Não é substituto de checagem de permissão: quem passa pelo CanTrustPlayer ainda depende do IsPlayerHasCustomPerms, que por padrão libera todo mundo. Se o seu servidor expõe o cliente a executores, implemente a checagem em IsPlayerHasCustomPerms (server/server.lua).
Os grupos são registrados em runtime com exports.qbx_core:CreateJobs e exports.qbx_core:CreateGangs a cada carregamento. O client também espelha o job atual nos statebags jobName, jobType e jobGrade do jogador, atualizados no login e em QBCore:Client:OnJobUpdate.
Fornece o boss menu (OpenBossMenu) aberto pelo ponto "Bossmenu", e recebe o item de gerenciamento de permissões de cargo. Se o recurso não estiver iniciado, o registro dos itens é simplesmente pulado.
O ponto de alarme dispara exports["ps-dispatch"]:CustomAlert para a job police, com a posição do jogador e o nome do grupo. Para trocar o dispatch ou as jobs alertadas, edite a função SendDispatch em config.lua.
O client lê GlobalState.UIColors para colorir os itens do menu (verde para ativo, vermelho para inativo). Sem o mri_Qbox, usa as mesmas cores por padrão.
-- true se o cargo do jogador tem a flag isboss-- groupType: 'job' | 'gang' | data: PlayerDataexports.mri_Qjobsystem:CheckPlayerIsbossByJobSystemData('job', QBX.PlayerData)-- true se o cargo do jogador tem a flag isrecruiterexports.mri_Qjobsystem:CheckPlayerIrecruiterByJobSystemData('gang', QBX.PlayerData)-- ordena uma lista de opções de menu pelo número entre colchetes no títuloexports.mri_Qjobsystem:SortByTitleIndex(options)
-- abre o assistente de criação (o comando /createjob dispara este evento)TriggerClientEvent('mri_Qjobsystem:client:createjob', source)-- abre o menu de gerenciamento; recebe a lista de gruposTriggerClientEvent('mri_Qjobsystem:client:openJobMenu', source, Jobs)-- envia a lista de grupos e recria os pontos no mundoTriggerClientEvent('mri_Qjobsystem:client:Pull', -1, Jobs)
Os eventos de escrita no servidor (saveNewJob, saveJob, deleteJob, createItem, makeRegisterAction, createBackup, setBackup, pullChanges) exigem o token do TriggerSecureEvent e não funcionam com TriggerServerEvent comum.
mri_Qjobsystem/├── client/│ ├── client.lua — cria os pontos no mundo (crafting, duty, cofre, alarme, bossmenu) e o menu de crafting│ ├── creation.lua — assistente /createjob e todo o menu de gerenciamento, incluindo permissões de cargo│ └── utilities.lua — exports de checagem de boss/recruiter e ordenação de menus├── server/│ ├── server.lua — carrega os grupos, registra em qbx_core, eventos de CRUD, cofre, backup e comandos│ ├── db.lua — queries oxmysql (tabela mri_qjobsystem e leitura de player_groups)│ ├── jobs.json — seed inicial dos grupos (usado só quando a tabela está vazia)│ └── backup.json — backup gerado pelo menu├── BRIDGE/│ ├── config.lua — framework, inventário, target e markers│ ├── client/│ │ ├── inventory.lua — itens, contagem e stash no client│ │ └── target.lua — sphere zones e model targets (ox_target / qb_target / markers)│ └── server/│ ├── framework.lua — player data, job/gang, dinheiro da society, item usável│ └── inventory.lua — add/remove item, registrar e limpar stash, drops├── secure.lua — token anti-trigger externo (TriggerSecureEvent / CanTrustPlayer)├── config.lua — animações, tipos de job, blacklist, bossmenu e dispatch├── locales/│ ├── en.json│ └── pt-br.json└── fxmanifest.lua