Panel de administración
hz_lib incluye un panel de administración centralizado en el que se conecta cada módulo HZ-Script. En lugar de que cada script traiga su propio comando e interfaz de configuración, todo está detrás de un único /hzpanel accesible para los admins. El panel construye automáticamente un editor tipado para cada campo de configuración declarado en el bridge_schema.lua de cada módulo.
Abrir el panel
En el juego (chat, consola F8 o atajo de teclado):
/hzpanel
- Solo consola (F8 del servidor):
/hzpaneldesde la consola del servidor no abre la NUI. Escríbelo desde el juego. - Requiere el permiso ACE configurado en
HZBridge.Panel.AcePermission(por defectoadmin). Consulta Configurar los permisos más abajo. - Pulsa
Escapeo el botón de cerrar para salir. Las sesiones están protegidas por token y caducan trasHZBridge.Panel.SessionTokenTtlMssin actividad (5 min por defecto): vuelve a abrir el panel para renovarla.
-- server export — opens the panel for `src` and preselects the named module
exports['hz_lib']:OpenPanel(src, 'hz_weather')
Configurar los permisos
El panel está protegido por el nodo ACE canónico admin de FXServer. Hacen falta dos líneas en server.cfg:
add_principal identifier.license:YOUR_LICENSE group.admin
add_ace group.admin admin allow
Sustituye YOUR_LICENSE por la licencia del jugador en tu servidor (la ves al escribir /hzpanel una vez: la salida de consola del fallo muestra todos tus identificadores y un bloque listo para copiar con tu licencia ya incluida).
Puedes pegar las dos líneas directamente en la consola del servidor para arreglarlo al instante, sin reiniciar. Si las pones en server.cfg, reinicia FXServer (o vuelve a ejecutar exec server.cfg) para cargarlas.
add_ace group.admin command allow en server.cfg pero no add_ace group.admin admin allow. El menú admin de qb-core usa su tabla de base de datos qbcore_admins en lugar del nodo ACE canónico admin, por eso falta la línea. Casi todos los tickets de permisos de hz_lib vienen de aquí: añade la segunda línea y listo.Un jugador que tiene el ACE command (puede ejecutar cualquier comando) también puede abrir el panel. En el primer arranque, los grupos admin del framework (admin, god, superadmin, owner en ESX, QBCore, QBox u Ox Core) se añaden como roles de staff con acceso completo a los módulos, así que los admins gestionados por tu framework pueden abrir el panel sin configurar ACE. Aun así, ACE es el método recomendado porque no depende del framework y se audita en un solo sitio.
Si la comprobación falla, la consola del servidor muestra:
- El nodo ACE exacto comprobado
- Todos tus identificadores de jugador
- Una matriz de prueba ACE (qué nodos están concedidos y cuáles no)
- Las dos líneas exactas
add_principal+add_acepara copiar, con tu licencia ya incluida
command.hzpanel NO da acceso al panel. Un error habitual es probar add_ace identifier.X command.hzpanel allow. hz_lib no usa ese nodo: la comprobación se hace sobre el AcePermission configurado (por defecto admin), no sobre el nombre del comando.Nodo ACE personalizado
Si no quieres usar el nodo canónico admin (por ejemplo, quieres que solo una parte del staff abra el panel sin darle todos los demás comandos de admin), configura un nodo propio en config.lua:
HZBridge.Panel.AcePermission = 'hzbridge.panel.admin'
Y después en server.cfg:
add_principal identifier.license:YOUR_LICENSE group.hzbridge.staff
add_ace group.hzbridge.staff hzbridge.panel.admin allow
El valor de respaldo (cuando AcePermission es nil o '') es 'admin', alineado con el valor por defecto de la configuración desde v1.1.1. Las versiones anteriores usaban 'hz_lib.admin' como respaldo, lo que bloqueaba a los clientes que solo tenían concedido el ACE canónico admin. Actualiza a v1.1.1 o superior si te afecta.
Roles del staff
El acceso no es todo o nada: cada rol de staff recibe, módulo por módulo, uno o varios de estos tres derechos.
| Derecho | Permite |
|---|---|
| view | Leer los ajustes del módulo |
| config | Cambiar sus ajustes guardados |
| manage | Usar sus acciones en directo (por ejemplo, cambiar el clima ahora) |
- Edita los roles en /hzpanel > Access control. Solo ve esta pestaña un rol con permiso para editar los accesos, y solo un grupo ACE puede tener ese permiso.
- En el primer arranque, el grupo detrás de
AcePermission(group.adminpor defecto) recibe acceso completo y el derecho de editar los accesos, así que instalar hz_lib no deja a nadie fuera. - Un jugador cuyos grupos no coinciden con ningún rol conserva el acceso completo si tiene
AcePermissionocommand. Un jugador que coincide con un rol conserva los límites de ese rol. - Los derechos se comprueban en cada acción: un admin degradado pierde el acceso incluso con el panel ya abierto.
- ¿Te has quedado fuera? Ejecuta
hzaccess_recover <grupo>en la consola del servidor (por ejemplohzaccess_recover admin).
Qué puedes modificar
El panel detecta automáticamente cada recurso que incluye un archivo bridge_schema.lua en su raíz. Con hz_lib v1.2.0, estos recursos HZ incluyen un esquema y tienen su propia pestaña:
| Módulo | Qué puedes ajustar |
|---|---|
| hz_lib | Tema global: acento, superficies, modo degradado, escala de esquinas, fuentes, posición del seguimiento de objetivos |
| HZ-Weather | Zonas (editor + mapa), pronóstico, hora, estaciones, eventos, configuración |
| HZ-Television | Canales, valores por defecto, opciones de rendimiento |
| HZ-Loading | Loading Creator (editor en directo de la pantalla de carga), telemetría |
| HZ-PauseMenu | Ajustes generales, imagen del servidor, integración con el HUD |
| HZ-TextUi | TextUI Designer (aspecto de los avisos) |
| HZ-Banking | Funciones, economía, imagen de marca, acceso, cuentas compartidas, efectivo y atracos, costes y límites, ahorros, préstamos, facturas (1.0.1) |
| HZ-Fuel (1.0.1) | Pago, precios del combustible, de la carga y del bidón, consumo, paga y fianza del repartidor |
| HZ-Bets | Cuotas, límites de apuesta, fuentes de eventos |
bridge_schema.lua: consulta la sección del DSL de esquema más abajo.
Un valor guardado en el panel manda sobre el archivo de config del propio script. Un punto marca cada ajuste cambiado en el panel, y su botón de restablecer borra el valor del panel: el ajuste vuelve a seguir el archivo de config del script (hz_lib 1.2.1 o posterior). Hasta hz_lib 1.2.0, el botón de restablecer guardaba en su lugar el valor por defecto del propio panel.
El DSL de esquema
El bridge_schema.lua de cada módulo es un pequeño DSL en Lua que declara la configuración que muestra el panel. El DSL se ejecuta en un entorno aislado (sin _G, sin io directo, con subconjuntos limitados de string / table / math), así que un esquema con errores o malicioso no puede romper el servidor.
Ejemplo 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)
Eso es todo: abre /hzpanel, aparece la pestaña "Your Script" con dos campos tipados, y los cambios se escriben en disco y se envían a cada cliente suscrito.
Tipos de campo
| Tipo | Se muestra como | Notas |
|---|---|---|
boolean | Interruptor | |
number | Campo numérico con min / max / step | Variante deslizador cuando step ≤ 1 y el rango está acotado |
string | Campo de texto, pattern + maxLength opcionales | |
enum | Lista desplegable (una opción) | Opciones con choices = { 'a', 'b', 'c' } |
enum-multi | Selección múltiple limitada (chips) | Nuevo en v1.1.0, se guarda como list<string> |
color | Selector de color hex | Validado como #RRGGBB |
keybind | Captura de atajo (tecla + modificadores) | |
list<string> | Campo de etiquetas (añadir/quitar libre) | |
list<object> | Editor de tabla en línea con columnas itemSchema | |
vehicle-list | Cuadrícula de selección de vehículos | Se rellena automáticamente desde GetAllVehicleModels() |
weapon-list | Cuadrícula de selección de armas | Catálogo fijo integrado en el panel |
action | Botón que lanza un evento de servidor | Para acciones tipo "Aplicar preset" / "Reset" |
enum-action | Lista desplegable de acciones | |
view | Componente React personalizado a todo el ancho | Integrado en el panel de hz_lib, consulta Vistas personalizadas más abajo |
Secciones, grupos, pestañas
section(id, { label, tab, dependsOn }, body): agrupación visual dentro de la pestaña de un módulo.tabes el id de la subpestaña (declarada conmodule(name, { tabs = { ... } })).dependsOn = { field = 'X', equals = true }pliega la sección cuando la condición es falsa.group(id, { label }, body): grupo plegable dentro de una sección.field(id, type, opts): un campo.optsadmitedefault,description,requiresRestart,serverOnly,deprecated,hidden,dependsOn, además de los extras propios de cada tipo.serverOnly = truedeja el valor en el servidor (nunca se envía a los jugadores): úsalo para secretos como las URL de webhook.invariant(sectionId, fn): validación entre campos. Se ejecuta en cada intento de guardado. Devuelvenil(ok) o un texto (mensaje de error).migrations({ [N] = function(values) ... end }): subeschemaVersione incluye una migración para reescribir los valores guardados antiguos.
Vistas personalizadas
Algunos scripts HZ necesitan algo más que un formulario: un editor de mapa, un gráfico de pronóstico, un editor de pantalla de carga. Declaran un campo view, con una lista events de los eventos de servidor que la vista puede lanzar. El componente React en sí está integrado en el panel de hz_lib, cuyo código fuente no se entrega: un esquema de terceros usa los tipos de campo de arriba.
HZ-Weather incluye seis vistas: Map, ZoneEditor, Events, Forecast, SeasonsPanel, TimePanel.
Cascada de tema (Appearance)
La pestaña Appearance de hz_lib centraliza los valores visuales que comparten todas las NUI HZ. Un solo cambio vuelve a colorear HZ-Weather, HZ-AudioMixer y HZ-Television en directo, sin reiniciar. Los nuevos scripts que se conectan heredan la cascada automáticamente siempre que su NUI lea las variables CSS canónicas --hz-*.
Ejes que controlas
| Eje | Claves | Efecto |
|---|---|---|
| Acento | accent / accentHi / gold | Color de firma, su variante al pasar el ratón y el color de los valores (dinero, XP). Por defecto: cian #00B4FF / #0095D9 / ámbar #FFB830. |
| Superficies | surface / subpanel / tint | Panel exterior / subpanel interior / tono al pasar el ratón. Solo RGB: cada consumidor decide la opacidad. |
| Modo degradado | gradientMode = 'gradient' \| 'solid' | solid (por defecto) convierte cada degradado de acento en un color plano, con un aspecto más sobrio. |
| Esquinas | radiusNone / Xs / Sm / Md / Lg / Xl | Escala de esquinas de seis niveles. Por defecto 0/4/8/12/16/20. |
| Fuentes | fontDisplay / fontBody / fontNumber | Fuentes de Google para títulos y etiquetas, texto y cifras. Por defecto Barlow Condensed / Barlow / Barlow Condensed. |
Posición del seguimiento de objetivos
La misma pestaña coloca el seguimiento de objetivos que muestran los trabajos y misiones HZ (consulta Seguimiento de objetivos):
| Ajuste | Valores | Efecto |
|---|---|---|
| Screen side | left (por defecto), right | Lado de la pantalla donde se listan los pasos |
| Height (% from the top) | 0 a 90 (por defecto 26) | Súbelo si la lista tapa otro elemento del HUD |
Cómo lo usan los módulos
El contenido completo se envía cada vez que el admin guarda:
-- 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 contiene pilas de fuentes CSS listas para usar y la URL de una hoja de Google Fonts (href). En tu NUI, escribe cada clave como variable CSS en :root (por ejemplo --hz-accent-rgb, --hz-surface-rgb, --hz-radius-md). Los componentes usan las variables con rgb(var(--hz-accent-rgb) / 0.45) / var(--hz-radius-md), así que la cascada es automática.
Obtén el tema actual de forma síncrona al arrancar (servidor):
local theme = exports['hz_lib']:GetTheme()
O pídelo con TriggerServerEvent('HZ-Bridge:theme:request'): el servidor responde con TriggerClientEvent('HZ-Bridge:theme:updated', src, theme).
'@hz_lib/ui/relay.lua' a tus client_scripts y carga https://cfx-nui-hz_lib/ui/hz-ui.css y https://cfx-nui-hz_lib/ui/hz-ui.js en tu página. El relé envía el tema a tu NUI y el kit lo aplica, al cargar y en cada cambio.Seguridad + auditoría
- Esquemas aislados: el DSL se ejecuta sin
io,osnidebugdirectos, y con una biblioteca estándar limitada. Unbridge_schema.luacon errores puede fallar al cargar (queda en el log), pero no puede tumbar el servidor. - Escrituras limitadas: por defecto
10 escrituras cada 5 spor origen. Configurable conHZBridge.Panel.RateLimitWrites/RateLimitWindowMs. - Tokens de sesión: cada apertura del panel emite un token que caduca tras 5 minutos sin actividad; los tokens caducados reciben un nuevo arranque en la siguiente petición.
- Validación: cada guardado pasa por la validación del tipo de campo, las comprobaciones opcionales
pattern/min/maxy luego las funcionesinvariantde la sección antes de llegar al disco. - Log de auditoría: cada guardado aceptado escribe una línea en
data/_audit.log. Al pasar de 10 MB, el archivo se renombradata/_audit.<fecha>.<hora>.logy empieza uno nuevo. hz_lib nunca borra estos archivos (HZBridge.Panel.AuditRetentionDaysno se aplica en la v1.2.0): borra tú los antiguos si necesitas un límite de conservación. - Escrituras atómicas: la configuración guardada de cada módulo se escribe en
data/<module>.jsonpasando antes por un archivo temporal. Los campos marcadosrequiresRestartquedan además pendientes endata/<module>.pending.jsony se aplican al reiniciar el recurso. - Derechos comprobados en cada acción, no solo al abrir el panel. Un admin al que se le retiran los derechos no puede seguir editando con el panel ya abierto.
Referencia
- Código del DSL de esquema:
modules/panel/schema_dsl.luaen tu carpeta de hz_lib (abierto, sin cifrar) - Configuración guardada por módulo:
data/<module>.json, másdata/<module>.pending.jsonpara los cambios que esperan un reinicio - Roles del staff:
data/_access.json - Auditoría:
data/_audit.log
