Documentación / API de integración

API de integración

Conecta tus scripts FiveM con Adictos_WebLogs: integration.lua, eventos, vehículos, gasolina/reparar en vivo (ox_fuel), servicios y jugador listo (ESX / QBCore / Qbox).

El archivo shared/integration.lua es la API pública de Adictos_WebLogs: funciona aunque el resto del recurso esté encriptado. Úsalo para registrar logs desde tus scripts, escuchar eventos del sistema o reaccionar cuando termina un CK o un cambio de licencia.

Incluir integration.lua en tu recurso

Añade el archivo como shared_script en el fxmanifest.lua de tu recurso. Las funciones de servidor (log, logPlayer, listeners) solo existen en el lado servidor; en cliente solo tienes AdictosWebLogs.isAvailable().

fx_version 'cerulean'
game 'gta5'

shared_scripts {
    '@Adictos_WebLogs/shared/integration.lua',
}

server_scripts {
    'server/main.lua',
}
Requisito: ensure Adictos_WebLogs debe ir antes o al menos estar iniciado cuando tu recurso registre logs. Comprueba con AdictosWebLogs.isAvailable() o GetResourceState('Adictos_WebLogs') == 'started'.

Funciones helper

FunciónDescripción
AdictosWebLogs.isAvailable()Devuelve true si el recurso Adictos_WebLogs está iniciado (cliente y servidor).
AdictosWebLogs.log(category, action, data, sendDiscord)Envía un log al panel. sendDiscord por defecto es true. Solo servidor.
AdictosWebLogs.logPlayer(source, category, action, data, sendDiscord)Igual que log pero rellena licencia y nombres desde el source del jugador. Solo servidor.
AdictosWebLogs.logVehicle(action, source, data, sendDiscord)Recomendado para vehículos. Una sola función para garaje, fuel, reparar, transferir y borrar. Ver sección dedicada.
AdictosWebLogs.onLog(handler)Escucha cada log aceptado: handler(category, action, logEntry).
AdictosWebLogs.onConfigLoaded(handler)Se dispara cuando WebLogs carga la configuración remota del panel.
AdictosWebLogs.onCKDone(handler)Se dispara al terminar un CK: handler(identifier, success, totalDeleted).
AdictosWebLogs.onLicenseTransferDone(handler)Se dispara al terminar un cambio de licencia: handler(oldLicense, newLicense, success, stats).
exports['Adictos_WebLogs']:ShowPendingWarnings(playerId)Muestra al jugador los avisos del panel aún no vistos (pantalla roja). Ver sección dedicada más abajo.

Ejemplo básico

local function logVenta(source, plate, precio)
    if not AdictosWebLogs.isAvailable() then return end

    AdictosWebLogs.logPlayer(source, 'vehicles', 'vehicle_sell', {
        details = ('Vendió %s por $%s'):format(plate, precio),
        raw_data = { plate = plate, price = precio },
    }, true)
end

Eventos del sistema

Los nombres oficiales están en AdictosWebLogs.Events. Puedes usarlos con AddEventHandler o los helpers de integration.lua:

ConstanteEventoCuándo se dispara
LOG_QUEUEDAdictos_WebLogs:onLogQueuedCada vez que un log entra en la cola (antes de enviarse al panel).
LOGS_SENTAdictos_WebLogs:onLogsSentTras enviar un lote de logs al panel.
CONFIG_LOADEDAdictos_WebLogs:onConfigLoadedConfiguración remota cargada (categorías, CK, etc.).
CONFIG_UPDATEDAdictos_WebLogs:onConfigUpdatedEl panel empuja cambios de configuración en caliente.
CK_DONEAdictos_WebLogs:onCKDoneCK completado desde el panel.
LICENSE_TRANSFER_DONEAdictos_WebLogs:onLicenseTransferDoneCambio de licencia completado.
PLAYER_BANNEDadictos:playerBannedBan aplicado desde el panel o sistema de sanciones.
PERMABAN_REQUESTadictos:webPermabanRequestSolicitud de permaban desde el panel.
-- Escuchar todos los logs de vehículos
AdictosWebLogs.onLog(function(category, action, entry)
    if category ~= 'vehicles' and category ~= 'vehicles_garage' then return end
    print(('[WebLogs] %s / %s — %s'):format(category, action, entry.details or ''))
end)

-- O con AddEventHandler directamente
AddEventHandler(AdictosWebLogs.Events.CONFIG_LOADED, function()
    print('WebLogs: categorías sincronizadas con el panel')
end)

Exports alternativos (sin integration.lua)

Si no quieres incluir el archivo compartido, puedes llamar a los exports del recurso o disparar eventos de red internos:

exports['Adictos_WebLogs']:Log('economy', 'payment', { amount = 500, details = 'Pago nómina' }, true)
exports['Adictos_WebLogs']:LogPlayer(source, 'jobs', 'duty_on', { details = 'Entró de servicio' })

-- Mismo efecto vía evento (servidor)
TriggerEvent('Adictos_WebLogs:Log', 'general', 'custom_event', { details = '...' }, false)

-- Lista de eventos disponibles
local events = exports['Adictos_WebLogs']:GetEvents()
El export Log() también acepta un objeto único con campos category, action, license, player_name, etc. Útil si ya tienes una tabla de datos montada (como en esx_advancedgarage).

API unificada de vehículos (recomendada)

No necesitas AdvancedParking, ox_fuel, esx_advancedgarage ni ningún script concreto. Solo llama a logVehicle() desde tu garaje, sistema de combustible o mecánico cuando la acción se complete en la base de datos. WebLogs se encarga de la categoría, la acción y el texto del log.

Acciones disponibles

AcciónConstanteCuándo llamarla
Guardar en garajestore o AdictosWebLogs.VehicleActions.STORETras marcar el vehículo como guardado en BD
Sacar del garajeretrieveTras spawnear el vehículo al jugador
RepararrepairTras actualizar motor/carrocería en BD o entidad
GasolinafuelTras cambiar el nivel de combustible
TransferirtransferTras cambiar el dueño en BD
BorrardeleteTras eliminar el registro de la BD

Campos de <code>data</code>

CampoDescripción
plateObligatorio. Matrícula del vehículo.
fuel / fuel_before / fuel_afterNivel de combustible (0–100).
engine_health / old_engineSalud del motor (0–1000 en GTA).
new_owner / targetLicense / targetNameNuevo propietario (transferencias).
detailsTexto libre; si no lo pones, WebLogs genera uno automático.
via = 'panel'Marca que la acción vino del panel web (staff).

Ejemplo — cualquier script de garaje (servidor)

shared_scripts { '@Adictos_WebLogs/shared/integration.lua' }

-- Tras guardar en TU tabla owned_vehicles / player_vehicles:
AdictosWebLogs.logVehicle(AdictosWebLogs.VehicleActions.STORE, source, {
    plate = plate,
    fuel = fuelLevel,
    engine_health = engineHealth,
})

-- Tras sacar del garaje:
AdictosWebLogs.logVehicle('retrieve', source, { plate = plate, engine_health = engineHealth })

Ejemplo — script de combustible (servidor)

-- Funciona con LegacyFuel, ps-fuel, ox_fuel, CDN-fuel o script propio
RegisterNetEvent('mi_fuel:pagado', function(plate, oldFuel, newFuel)
    AdictosWebLogs.logVehicle('fuel', source, {
        plate = plate,
        fuel_before = oldFuel,
        fuel_after = newFuel,
    })
end)

Ejemplo — mecánico / reparación

AdictosWebLogs.logVehicle('repair', source, {
    plate = plate,
    old_engine = engineHealthBefore,
})

Ejemplo — transferencia o borrado

AdictosWebLogs.logVehicle('transfer', adminSource, {
    plate = plate,
    new_owner = newOwnerLicense,
    targetName = newOwnerName,
})

AdictosWebLogs.logVehicle('delete', source, { plate = plate })

Desde cliente (si el evento nace en client)

-- En client.lua (con integration.lua cargado)
AdictosWebLogs.logVehicle('fuel', {
    plate = plate,
    fuel_before = 20,
    fuel_after = 100,
})

Sin integration.lua (solo export)

exports['Adictos_WebLogs']:LogVehicle('store', source, {
    plate = 'ABC 123',
    fuel = 75,
    engine_health = 900,
})
Las acciones del panel web (Garaje, Reparar, Gasolina, Transferir, Borrar en el perfil del jugador) ya registran log automáticamente con prefijo [Panel]. No hace falta código extra para eso.

Reparar / Gasolina en vivo (framework.lua)

Cuando el staff pulsa Reparar o Gasolina en Tickets, Mapa en vivo o el perfil del jugador, WebLogs actualiza la BD y, si el vehículo está spawneado, aplica el cambio en el mundo. La lógica vive en shared/framework.lua (archivo plano, no se encripta) para que puedas adaptarla a tu servidor.

Configura el preset en Mis servidores → Gestionar → Framework → Gasolina desde el panel (auto, ox_fuel, LegacyFuel, ps-fuel, solo BD, etc.).

API servidor (<code>WebLogsFramework</code>)

FunciónDescripción
getPanelFuelTargetLevel()Nivel 0–100 configurado en el panel (preset Framework).
applyPanelFuelLive(vehicleHandle, fuelLevel?)Rellena combustible en un vehículo spawneado según el preset (statebag ox_fuel, export SetFuel, evento custom o solo BD).
applyPanelRepairLive(vehicleHandle)Repara salud en servidor y dispara el fix visual/físico en todos los clientes.
updateVehicleFuel(plate, propsJson, fuelLevel?)UPDATE de la columna fuel + props JSON en owned_vehicles / player_vehicles.
updateVehicleRepair(plate, propsJson)UPDATE de motor/carrocería en BD.

API cliente (mismo archivo)

FunciónDescripción
applyClientVehicleFuel(vehicle, fuelLevel, exportResource?)Aplica SetVehicleFuelLevel (y SetFuel si hay export). Reaplica varios ticks para que ox_fuel no pise el nivel con el valor antiguo del nativo.
applyClientVehicleRepair(vehicle)SetVehicleFixed, deformación, motor/carrocería/tanque y suciedad. También lo usa el botón Reparar del APM.

Eventos de red

EventoParámetrosUso
Adictos_WebLogs:panelSetVehicleFuelnetId, fuelLevel, exportResourceServidor → clientes. exportResource vacío = solo nativo/statebag (ox_fuel).
Adictos_WebLogs:panelRepairVehiclenetIdServidor → clientes. Fix completo del vehículo streameado.

ox_fuel (recomendado)

  • Preset auto detecta ox_fuel primero; o fuerza preset ox_fuel (tipo statebag).
  • Servidor: Entity(veh).state:set('fuel', level, true) — fuente de verdad de ox_fuel.
  • Clientes: SetVehicleFuelLevel obligatorio si alguien conduce; si no, el loop de ox_fuel vuelve a bajar el depósito con GetVehicleFuelLevel.
  • No uses el evento cliente ox_fuel:setFuel para subir gasolina: en servidor es reduceOnly (solo baja).
  • ox_fuel no exporta SetFuel; no elijas preset LegacyFuel si usas ox_fuel.
-- Ejemplo: rellenar / reparar un vehículo spawneado desde tu script (servidor)
local veh = -- handle de entidad del vehículo
if veh and DoesEntityExist(veh) then
    local level = WebLogsFramework.getPanelFuelTargetLevel()
    WebLogsFramework.applyPanelFuelLive(veh, level)
    WebLogsFramework.applyPanelRepairLive(veh)
end

-- Cliente (p. ej. menú admin propio)
WebLogsFramework.applyClientVehicleRepair(cache.vehicle)
WebLogsFramework.applyClientVehicleFuel(cache.vehicle, 100)
Si personalizas el comportamiento, edita shared/framework.lua en la carpeta del recurso (se conserva en actualizaciones encriptadas). Evita tocar server/map_panel.lua ofuscado salvo que sepas qué cambia el builder.

Integraciones opcionales (no obligatorias)

  • esx_advancedgarage — ya integrado; usa LogVehicle internamente.
  • AdvancedParking — solo afecta al mapa en vivo y al borrado automático; los logs de garaje/fuel los pones tú con logVehicle.
  • Hook de borrado — opcional; detecta DeleteEntity sin que programes nada (ver abajo).

Logs de vehículos — referencia de categorías

SituaciónCategoría sugeridaAcción (action)Notas
Enviar vehículo al garajevehicles_garagevehicle_storeCrea la categoría vehicles_garage en el panel si no existe.
Sacar vehículo del garajevehicles_garagevehicle_retrieveMisma categoría que guardar.
Reparar vehículovehiclesvehicle_repairIncluye matrícula y % de motor antes/después en details o raw_data.
Echar / llenar gasolinavehiclesvehicle_fuelIndica nivel anterior y nuevo (0–100).
Transferir propiedadvehiclesvehicle_transferUsa targetLicense / targetName para el nuevo dueño.
Borrar vehículo (script propio)vehiclesvehicle_deleteUsa logVehicle('delete', …) o ReportVehicleDelete.
Prefiere siempre logVehicle() en lugar de montar categoría y acción a mano: así tus logs serán consistentes con el panel y con otros servidores.

Hook automático de borrado (otros recursos)

Si tu recurso llama a DeleteEntity o DeleteVehicle sobre coches, puedes cargar el hook compartido para que WebLogs registre el borrado con el nombre de tu script:

shared_scripts {
    '@Adictos_WebLogs/hooks/vehicle_delete_hook.lua',  -- después de otros hooks de AP si los hay
}
Adictos_WebLogs debe estar en el servidor (carpeta del recurso con hooks/vehicle_delete_hook.lua). Ese archivo va en files {} del manifiesto de WebLogs; si falta, el cliente muestra Failed to load script @Adictos_WebLogs/hooks/vehicle_delete_hook.lua. Añade Adictos_WebLogs a dependencies del recurso que carga el hook.

El monitor unificado de WebLogs fusiona estos reportes con eventos de AdvancedParking y avisos de “vehículo perdido mientras conduces”. Configurable en el panel → Mis servidores → Gestionar → pestaña de vehículos.

Referencia rápida de categorías de vehículos

  • vehicles — acciones generales (spawn, delete, subir/bajar, reparar, fuel, transferir…)
  • vehicles_garage — guardar y sacar de garaje
  • vehicles_engine, vehicles_tuning, vehicles_build — otros módulos del panel (crea y activa las que uses)
Los identificadores de categoría deben existir y estar activos en Mis servidores → Categorías. Si no, el log puede no mostrarse en el filtro esperado.

Export ShowPendingWarnings (avisos in-game)

Muestra al jugador la pantalla roja de aviso con todos los avisos del panel que aún no ha confirmado (seen_at vacío). Si hay varios, salen en el mismo mensaje (numerados). El jugador debe mantener ESPACIO unos segundos para marcarlos como vistos.

Útil cuando en Mis servidores → Gestionar → Personalización tienes desactivado «Mostrar avisos automáticamente» y quieres forzar la notificación desde tu script (jail, menú admin, al salir de un menú, etc.).

-- playerId = source del jugador (server ID de FiveM)
if GetResourceState('Adictos_WebLogs') ~= 'started' then return end

local ok = exports['Adictos_WebLogs']:ShowPendingWarnings(playerId)
if not ok then
    -- Jugador offline, ID inválido, o ya hay una petición en curso
    print('No se pudieron mostrar avisos pendientes')
end
Parámetro / retornoDescripción
playerIdSource del jugador en el servidor (source). Obligatorio
Retorno trueSe ha lanzado la consulta de avisos pendientes al panel
Retorno falseJugador no conectado, ID inválido, o export ocupado para ese jugador

Comportamiento

  • Consulta al panel los avisos con seen_at vacío de esa licencia.
  • Si no hay pendientes, no muestra nada.
  • Si hay 1 aviso: pantalla «Aviso» con el motivo y el staff.
  • Si hay 2 o más: título «Avisos (N)» y texto combinado [1/N] … / [2/N] … en la misma pantalla.
  • Al completar el hold de ESPACIO, todos los IDs mostrados pasan a Visto en el panel y no se vuelven a mostrar.
  • Funciona aunque el toggle de notificación automática esté desactivado.

Ejemplo: al liberar de jail

RegisterNetEvent('mi_script:playerReleasedFromJail', function()
    local src = source
    if GetResourceState('Adictos_WebLogs') == 'started' then
        exports['Adictos_WebLogs']:ShowPendingWarnings(src)
    end
end)
La notificación automática (al avisar desde el panel o al conectar) se configura en Mis servidores → Gestionar → Personalización → Avisos in-game. El export no depende de ese ajuste.

Export AssignCommunityService / SendToCommunityService

Servicios comunitarios integrados en Adictos_WebLogs (sustituye esx_communityservice). La zona, puntos de trabajo, animaciones y ropa (números skinchanger hombre/mujer) se configuran en Mis servidores → Gestionar → Servicios. También desde /apm puedes colocar puntos y capturar ropa con ROPA HOMBRE / ROPA MUJER.

-- Por source (jugador online)
exports['Adictos_WebLogs']:SendToCommunityService(playerId, 10, 'Motivo')

-- Por licencia (panel / scripts)
exports['Adictos_WebLogs']:AssignCommunityService({
    license = 'abc123...',
    actions = 10,
    motivo = 'VDM',
})
  • Activa el módulo en Gestionar → Servicios y quita ensure esx_communityservice del server.cfg (no ejecutes ambos a la vez).
  • Si «Mostrar aviso al asignar» está ON, el jugador ve la pantalla roja con el motivo.
  • Compatibilidad (ya dentro de WebLogs): eventos esx_serviciocomunitario:sendToCommunityService / esx_communityservice:….

Jugador cargado / listo (ESX, QBCore y Qbox)

API genérica para saber cuándo el personaje está cargado y cuándo el jugador está realmente listo en el mundo. Funciona con o sin multicharacter.

Hay dos niveles. Registra handlers en el servidor (WebLogsFramework en shared/framework.lua, o exports):

NivelAPICuándo
1. PersonajeonPlayerLoaded / IsCharacterLoadedEl core ya tiene el xPlayer / Player (tras elegir char en multichar, o al cargar sin multichar)
2. Listo en mundoonPlayerFullyReady / IsPlayerFullyReadyAdemás el cliente confirma ped activo, vivo y con coordenadas válidas
playerConnecting / playerJoining
    │
    ▼
Multichar (opcional) → elige personaje
    │
    ▼
esx:playerLoaded / QBCore:OnPlayerLoaded / qbx_core:…
    │
    ▼
WebLogsFramework.onPlayerLoaded  ← personaje en framework
    │
    ▼
Cliente ACK (ped vivo + coords)
    │
    ▼
WebLogsFramework.onPlayerFullyReady  ← listo en el mundo

Uso recomendado

-- Esperar a que el jugador esté jugable (avisos, premios, TP, etc.)
WebLogsFramework.onPlayerFullyReady(function(playerId, meta)
    -- meta.alive, meta.coords, meta.framework ('esx' | 'qb' | 'qbx')
    print(('Jugador %s listo (%s)'):format(playerId, tostring(meta.framework)))
end)

-- Solo personaje en framework (sin esperar ped)
WebLogsFramework.onPlayerLoaded(function(playerId)
    print('Personaje cargado: ' .. playerId)
end)

-- Exports equivalentes (desde otro recurso)
exports['Adictos_WebLogs']:OnPlayerFullyReady(function(src, meta) end)
exports['Adictos_WebLogs']:OnPlayerLoaded(function(src) end)

if exports['Adictos_WebLogs']:IsPlayerFullyReady(src) then
    -- ped listo
end
if exports['Adictos_WebLogs']:IsCharacterLoaded(src) then
    -- personaje en framework
end
Export / funciónDescripción
OnPlayerLoaded(handler)Callback cuando el personaje está en el framework
OnPlayerFullyReady(handler)Callback cuando el ped está listo en el mundo (handler(src, meta))
IsCharacterLoaded(src)Boolean: personaje cargado
IsPlayerFullyReady(src)Boolean: ACK de cliente recibido
WebLogsFramework.getName()Devuelve esx, qb o qbx

Opciones (Custom en framework.lua)

OpciónPor defectoUso
playerReadyDelayMs1500Espera tras personaje cargado (multichar / inventario) antes de pedir ACK
playerReadyRequireAlivetrueExige ped vivo + coords válidas en el cliente
playerReadyTimeoutMs600000Tiempo máximo esperando el ACK (ms; mínimo interno 30 s)
Avisos in-game y premios de sorteos usan onPlayerFullyReady internamente, para no mostrar UI antes de que el ped exista.
No uses playerConnecting / playerJoining para dar ítems o teleportar: el personaje puede no existir aún. Prefiere onPlayerFullyReady.