Painel de administração
O hz_lib traz um painel de administração centralizado ao qual cada módulo HZ-Script se conecta. Em vez de cada script trazer o seu próprio comando e interface de configuração, tudo fica atrás de um único /hzpanel acessível aos admins. O painel constrói automaticamente um editor tipado para cada campo de configuração declarado no bridge_schema.lua de cada módulo.
Abrir o painel
No jogo (chat, console F8 ou atalho de teclado):
/hzpanel
- Só no console (F8 do servidor):
/hzpanelno console do servidor não abre a NUI. Digite-o dentro do jogo. - Exige a permissão ACE configurada em
HZBridge.Panel.AcePermission(padrãoadmin). Veja Dar acesso ao painel mais abaixo. - Pressione
Escapeou o botão de fechar para sair. As sessões são protegidas por token e expiram apósHZBridge.Panel.SessionTokenTtlMssem atividade (5 min por padrão): abra o painel de novo para renovar.
-- server export — opens the panel for `src` and preselects the named module
exports['hz_lib']:OpenPanel(src, 'hz_weather')
Dar acesso ao painel
O painel é protegido pelo nó ACE canônico admin do FXServer. São necessárias duas linhas no server.cfg:
add_principal identifier.license:YOUR_LICENSE group.admin
add_ace group.admin admin allow
Troque YOUR_LICENSE pela licença do jogador no seu servidor (você a vê digitando /hzpanel uma vez: a saída do console da falha mostra todos os seus identificadores e um bloco pronto para copiar com a sua licença já preenchida).
Você pode colar as duas linhas direto no console do servidor para resolver na hora, sem reiniciar. Se colocá-las no server.cfg, reinicie o FXServer (ou execute exec server.cfg de novo) para carregá-las.
add_ace group.admin command allow no server.cfg, mas não add_ace group.admin admin allow. O menu admin do qb-core usa a tabela de banco de dados qbcore_admins em vez do nó ACE canônico admin, por isso a linha falta. Quase todo ticket de permissão do hz_lib vem daqui: adicione a segunda linha e pronto.Um jogador com o ACE command (pode executar qualquer comando) também pode abrir o painel. Na primeira inicialização, os grupos admin do framework (admin, god, superadmin, owner no ESX, QBCore, QBox ou Ox Core) são adicionados como cargos da staff com acesso total aos módulos, então os admins gerenciados pelo seu framework conseguem abrir o painel sem configurar o ACE. Mesmo assim, o ACE é o caminho recomendado, porque não depende do framework e pode ser auditado em um só lugar.
Se a verificação falhar, o console do servidor mostra:
- O nó ACE exato verificado
- Todos os seus identificadores de jogador
- Uma matriz de teste ACE (quais nós estão liberados e quais não)
- As duas linhas exatas
add_principal+add_acepara copiar, com a sua licença já preenchida
command.hzpanel NÃO dá acesso ao painel. Um erro comum é tentar add_ace identifier.X command.hzpanel allow. O hz_lib não usa esse nó: a verificação é feita no AcePermission configurado (padrão admin), não no nome do comando.Nó ACE personalizado
Se você não quiser usar o nó canônico admin (por exemplo, quer que só parte da staff abra o painel sem receber todos os outros comandos de admin), configure um nó próprio no config.lua:
HZBridge.Panel.AcePermission = 'hzbridge.panel.admin'
Depois, no server.cfg:
add_principal identifier.license:YOUR_LICENSE group.hzbridge.staff
add_ace group.hzbridge.staff hzbridge.panel.admin allow
O valor de reserva (quando AcePermission é nil ou '') é 'admin', alinhado com o padrão da configuração desde a v1.1.1. As versões anteriores usavam 'hz_lib.admin' como reserva, o que trancava do lado de fora os clientes que só tinham o ACE canônico admin. Atualize para a v1.1.1 ou superior se isso afetar você.
Cargos da staff
O acesso não é tudo ou nada: cada cargo da staff recebe, módulo por módulo, um ou mais destes três direitos.
| Direito | Permite |
|---|---|
| view | Ler as configurações do módulo |
| config | Alterar as configurações salvas dele |
| manage | Usar as ações ao vivo dele (por exemplo, mudar o clima agora) |
- Edite os cargos em /hzpanel > Access control. Só vê essa aba um cargo com permissão para editar os acessos, e só um grupo ACE pode receber essa permissão.
- Na primeira inicialização, o grupo por trás de
AcePermission(group.adminpor padrão) recebe acesso total e o direito de editar os acessos, então instalar o hz_lib não tranca ninguém do lado de fora. - Um jogador cujos grupos não correspondem a nenhum cargo mantém o acesso total se tiver
AcePermissionoucommand. Um jogador que corresponde a um cargo mantém os limites desse cargo. - Os direitos são verificados a cada ação: um admin rebaixado perde o acesso mesmo com o painel já aberto.
- Ficou sem acesso? Execute
hzaccess_recover <grupo>no console do servidor (por exemplohzaccess_recover admin).
O que você pode alterar
O painel detecta automaticamente cada recurso que traz um arquivo bridge_schema.lua na raiz. Com o hz_lib v1.2.0, estes recursos HZ trazem um schema e têm a sua própria aba:
| Módulo | O que você pode ajustar |
|---|---|
| hz_lib | Tema global: destaque, superfícies, modo degradê, escala de cantos, fontes, posição do rastreador de objetivos |
| HZ-Weather | Zonas (editor + mapa), previsão, hora, estações, eventos, configuração |
| HZ-Television | Canais, valores padrão, opções de desempenho |
| HZ-Loading | Loading Creator (editor ao vivo da tela de carregamento), telemetria |
| HZ-PauseMenu | Configurações gerais, identidade do servidor, integração com o HUD |
| HZ-TextUi | TextUI Designer (aparência dos avisos) |
| HZ-Banking | Funções, economia, identidade visual, acesso, contas compartilhadas, dinheiro e assaltos, custos e limites, poupança, empréstimos, faturas (1.0.1) |
| HZ-Fuel (1.0.1) | Pagamento, preços do combustível, da recarga e do galão, consumo, pagamento e depósito do entregador |
| HZ-Bets | Odds, limites de aposta, fontes de eventos |
bridge_schema.lua: veja a seção sobre a DSL de schema mais abaixo.
Um valor salvo no painel tem prioridade sobre o arquivo de config do próprio script. Um ponto marca cada ajuste alterado no painel, e o botão de redefinir dele apaga o valor do painel: o ajuste volta a seguir o arquivo de config do script (hz_lib 1.2.1 ou mais recente). Até o hz_lib 1.2.0, o botão de redefinir salvava no lugar o padrão do próprio painel.
A DSL de schema
O bridge_schema.lua de cada módulo é uma pequena DSL em Lua que declara a configuração exibida pelo painel. A DSL roda em um ambiente isolado (sem _G, sem io direto, com subconjuntos restritos de string / table / math), então um schema com erros ou malicioso não consegue quebrar o servidor.
Exemplo mínimo
-- resources/your-script/bridge_schema.lua
module('your-script', {
schemaVersion = 1,
label = { en = 'Your Script', fr = 'Ton script' },
}, function()
section('general', {
label = { en = 'General', fr = 'Général' },
}, function()
field('Enabled', 'boolean', {
default = true,
label = { en = 'Enabled', fr = 'Activé' },
description = {
en = 'Master on/off switch for the script.',
fr = 'Interrupteur global du script.',
},
})
field('PlayerLimit', 'number', {
default = 32, min = 1, max = 256, step = 1,
label = { en = 'Max concurrent players', fr = 'Joueurs simultanés max' },
})
end)
end)
É só isso: abra o /hzpanel, a aba "Your Script" aparece com dois campos tipados, e as alterações são gravadas no disco e enviadas a cada cliente inscrito.
Tipos de campo
| Tipo | Aparece como | Observações |
|---|---|---|
boolean | Interruptor | |
number | Campo numérico com min / max / step | Vira controle deslizante quando step ≤ 1 e o intervalo é limitado |
string | Campo de texto, pattern + maxLength opcionais | |
enum | Lista suspensa (uma escolha) | Opções via choices = { 'a', 'b', 'c' } |
enum-multi | Seleção múltipla limitada (chips) | Novo na v1.1.0, salvo como list<string> |
color | Seletor de cor hex | Validado como #RRGGBB |
keybind | Captura de atalho (tecla + modificadores) | |
list<string> | Campo de tags (adicionar/remover livremente) | |
list<object> | Editor de tabela em linha com colunas itemSchema | |
vehicle-list | Grade de seleção de veículos | Preenchida automaticamente a partir de GetAllVehicleModels() |
weapon-list | Grade de seleção de armas | Catálogo fixo embutido no painel |
action | Botão que dispara um evento de servidor | Para ações do tipo "Aplicar preset" / "Reset" |
enum-action | Lista suspensa de ações | |
view | Componente React personalizado em largura total | Embutido no painel do hz_lib, veja Visualizações personalizadas abaixo |
Seções, grupos, abas
section(id, { label, tab, dependsOn }, body): agrupamento visual dentro da aba de um módulo.tabé o id da subaba (declarada viamodule(name, { tabs = { ... } })).dependsOn = { field = 'X', equals = true }recolhe a seção quando a condição é falsa.group(id, { label }, body): grupo recolhível dentro de uma seção.field(id, type, opts): um campo.optsaceitadefault,description,requiresRestart,serverOnly,deprecated,hidden,dependsOn, além dos extras de cada tipo.serverOnly = truemantém o valor no servidor (nunca enviado aos jogadores): use para segredos como URLs de webhook.invariant(sectionId, fn): validação entre campos. Roda a cada tentativa de salvar. Retornanil(ok) ou um texto (mensagem de erro).migrations({ [N] = function(values) ... end }): aumenteschemaVersione inclua uma migração para reescrever os valores salvos antigos.
Visualizações personalizadas
Alguns scripts HZ precisam de mais do que um formulário: um editor de mapa, um gráfico de previsão, um editor de tela de carregamento. Eles declaram um campo view, com uma lista events dos eventos de servidor que a visualização pode disparar. O componente React em si fica embutido no painel do hz_lib, cujo código-fonte não é entregue: um schema de terceiros usa os tipos de campo acima.
O HZ-Weather traz seis visualizações: Map, ZoneEditor, Events, Forecast, SeasonsPanel, TimePanel.
Cascata de tema (Appearance)
A aba Appearance do hz_lib centraliza os valores visuais compartilhados por todas as NUIs HZ. Uma única alteração recolore HZ-Weather, HZ-AudioMixer e HZ-Television ao vivo, sem reiniciar. Novos scripts que se conectam herdam a cascata automaticamente, desde que a NUI deles leia as variáveis CSS canônicas --hz-*.
O que você controla
| Eixo | Chaves | Efeito |
|---|---|---|
| Destaque | accent / accentHi / gold | Cor de assinatura, a variante ao passar o mouse e a cor dos valores (dinheiro, XP). Padrão: ciano #00B4FF / #0095D9 / âmbar #FFB830. |
| Superfícies | surface / subpanel / tint | Painel externo / subpainel interno / tom ao passar o mouse. Só RGB: cada consumidor decide a opacidade. |
| Modo degradê | gradientMode = 'gradient' \| 'solid' | solid (padrão) transforma cada degradê de destaque em cor chapada, com um visual mais sóbrio. |
| Cantos | radiusNone / Xs / Sm / Md / Lg / Xl | Escala de cantos em seis níveis. Padrão 0/4/8/12/16/20. |
| Fontes | fontDisplay / fontBody / fontNumber | Fontes do Google para títulos e rótulos, texto e números. Padrão Barlow Condensed / Barlow / Barlow Condensed. |
Posição do rastreador de objetivos
A mesma aba posiciona o rastreador de objetivos exibido pelos trabalhos e missões HZ (veja Rastreador de objetivos):
| Ajuste | Valores | Efeito |
|---|---|---|
| Screen side | left (padrão), right | Lado da tela onde as etapas aparecem |
| Height (% from the top) | 0 a 90 (padrão 26) | Aumente se a lista cobrir outro elemento do HUD |
Como os módulos usam o tema
O conteúdo completo é enviado sempre que o admin salva:
-- server (any resource)
AddEventHandler('HZ-Bridge:theme:updated', function(theme)
-- theme: { preset, accent, accentHi, gold, surface, subpanel, tint,
-- gradientMode, radiusNone, radiusXs, radiusSm, ..., radiusXl,
-- fontDisplay, fontBody, fontNumber,
-- fonts = { display, body, number, href } }
end)
-- client
RegisterNetEvent('HZ-Bridge:theme:updated', function(theme)
SendNUIMessage({ action = 'theme', data = theme })
end)
fonts traz pilhas de fontes CSS prontas para uso e a URL de uma folha do Google Fonts (href). Na sua NUI, escreva cada chave como variável CSS em :root (por exemplo --hz-accent-rgb, --hz-surface-rgb, --hz-radius-md). Os componentes usam as variáveis via rgb(var(--hz-accent-rgb) / 0.45) / var(--hz-radius-md), então a cascata é automática.
Obtenha o tema atual de forma síncrona ao iniciar (servidor):
local theme = exports['hz_lib']:GetTheme()
Ou peça com TriggerServerEvent('HZ-Bridge:theme:request'): o servidor responde com TriggerClientEvent('HZ-Bridge:theme:updated', src, theme).
'@hz_lib/ui/relay.lua' aos seus client_scripts e carregue https://cfx-nui-hz_lib/ui/hz-ui.css e https://cfx-nui-hz_lib/ui/hz-ui.js na sua página. O relé envia o tema para a sua NUI e o kit o aplica, ao carregar e a cada alteração.Segurança + auditoria
- Schemas isolados: a DSL roda sem
io,osoudebugdiretos, com uma biblioteca padrão restrita. Umbridge_schema.luacom erros pode falhar ao carregar (fica no log), mas não derruba o servidor. - Gravações limitadas: por padrão
10 gravações a cada 5 spor origem. Configurável viaHZBridge.Panel.RateLimitWrites/RateLimitWindowMs. - Tokens de sessão: cada abertura do painel gera um token que expira após 5 minutos sem atividade; tokens expirados recebem uma nova inicialização na próxima requisição.
- Validação: cada salvamento passa pela validação do tipo de campo, pelas verificações opcionais
pattern/min/maxe depois pelas funçõesinvariantda seção antes de ir para o disco. - Log de auditoria: cada salvamento aceito grava uma linha em
data/_audit.log. Acima de 10 MB, o arquivo é renomeado paradata/_audit.<data>.<hora>.loge um novo começa. O hz_lib nunca apaga esses arquivos (HZBridge.Panel.AuditRetentionDaysnão é aplicado na v1.2.0): apague você mesmo os antigos se precisar de um limite de retenção. - Gravações atômicas: a configuração salva de cada módulo é gravada em
data/<module>.jsonpassando antes por um arquivo temporário. Campos marcados comrequiresRestarttambém ficam pendentes emdata/<module>.pending.jsone são aplicados quando o recurso reinicia. - Direitos verificados a cada ação, não só ao abrir o painel. Um admin que perde os direitos não consegue continuar editando com o painel já aberto.
Referência
- Código da DSL de schema:
modules/panel/schema_dsl.luana sua pasta do hz_lib (aberto, não criptografado) - Configuração salva por módulo:
data/<module>.json, maisdata/<module>.pending.jsonpara as alterações que esperam um reinício - Cargos da staff:
data/_access.json - Auditoria:
data/_audit.log
