Notificaciones y barras de progreso en FiveM: ESX, QBCore y ox_lib

Envía notificaciones y muestra barras de progreso en ESX, QBCore y ox_lib con ShowNotification, Functions.Notify, lib.notify y lib.progressBar, además una función puente.

Cada framework tiene su propia forma de mostrar un mensaje o una barra de progreso, y un script escrito para uno falla en otro:

text
attempt to index a nil value (global 'lib')

Este artículo enumera las llamadas para ESX, QBCore y ox_lib, para notificaciones y para barras de progreso, luego muestra una única función puente para que tu script funcione en el que sea que el servidor ejecute.

Notificaciones en ESX

En el cliente:

lua
ESX.ShowNotification('You picked up a package')

En el servidor, desde el objeto del jugador:

lua
local xPlayer = ESX.GetPlayerFromId(source)
xPlayer.showNotification('Your order is ready')

ESX aquí es el objeto de ESX = exports['es_extended']:getSharedObject(). Las versiones recientes de ESX también aceptan un tipo y una duración después del texto. Si dependes de ellos, prueba en tu versión.

Notificaciones en QBCore

En el cliente:

lua
local QBCore = exports['qb-core']:GetCoreObject()

QBCore.Functions.Notify('You picked up a package', 'success', 5000)

El tipo es 'primary', 'success' o 'error', y el último valor es el tiempo en milisegundos. Desde el servidor, envía el evento al jugador:

lua
TriggerClientEvent('QBCore:Notify', source, 'Your order is ready', 'success')

En QBox las mismas llamadas de QBCore siguen funcionando a través de su capa de compatibilidad, y las notificaciones de ox_lib son una buena alternativa.

Notificaciones con ox_lib

ox_lib tiene su propia notificación, y funciona igual en cada framework. En el cliente:

lua
lib.notify({
    title = 'Delivery',
    description = 'You picked up a package',
    type = 'success',
    duration = 5000,
})

El tipo es 'inform', 'success', 'warning' o 'error'. Desde el servidor, dispara el evento en el jugador:

lua
TriggerClientEvent('ox_lib:notify', source, {
    title = 'Delivery',
    description = 'Your order is ready',
    type = 'success',
})

El global lib necesita shared_script '@ox_lib/init.lua' en tu fxmanifest.lua, como se describe en the ox_lib context menu guide. Sin él obtienes el error de lib nil arriba.

Barras de progreso

Con ox_lib, una barra de progreso es una llamada que espera y devuelve si terminó:

lua
if lib.progressBar({
    duration = 5000,
    label = 'Repairing the engine',
    useWhileDead = false,
    canCancel = true,
    disable = {
        move = true,
        car = true,
        combat = true,
    },
    anim = {
        dict = 'mini@repair',
        clip = 'fixing_a_ped',
    },
}) then
    print('finished')
else
    print('cancelled')
end

lib.progressCircle toma las mismas opciones y muestra un círculo en lugar de una barra. Ambas también pueden adjuntar un prop al jugador.

La versión de QBCore usa una devolución de llamada en lugar de esperar:

lua
QBCore.Functions.Progressbar('repair_engine', 'Repairing the engine', 5000, false, true, {
    disableMovement = true,
    disableCarMovement = true,
    disableMouse = false,
    disableCombat = true,
}, {
    animDict = 'mini@repair',
    anim = 'fixing_a_ped',
    flags = 49,
}, {}, {}, function()
    print('finished')
end, function()
    print('cancelled')
end)

Los argumentos son, en orden: un nombre, la etiqueta, la duración, useWhileDead, canCancel, los controles deshabilitados, la animación, dos props, luego los callbacks de finalización y cancelación. ESX no tiene su propia barra de progreso que cada servidor comparta, así que en ESX usa lib.progressBar.

Una función puente para todos ellos

Para mantener tus scripts libres de framework, escribe el detalle del framework una vez y llama a tus propias funciones en todas partes. Pon esto en un archivo del cliente:

lua
local function started(name)
    return GetResourceState(name) == 'started'
end

function Notify(message, notifyType)
    notifyType = notifyType or 'inform'

    if started('ox_lib') then
        lib.notify({ description = message, type = notifyType })
    elseif started('qb-core') then
        local qbType = notifyType == 'inform' and 'primary' or notifyType
        exports['qb-core']:GetCoreObject().Functions.Notify(message, qbType)
    elseif started('es_extended') then
        exports['es_extended']:getSharedObject().ShowNotification(message)
    else
        print(message)
    end
end

-- returns true when finished, false when cancelled
function Progress(label, duration)
    if started('ox_lib') then
        return lib.progressBar({
            duration = duration,
            label = label,
            canCancel = true,
            disable = { move = true, car = true },
        })
    end

    local p = promise.new()
    exports['qb-core']:GetCoreObject().Functions.Progressbar('bridge_progress', label, duration, false, true, {
        disableMovement = true,
        disableCarMovement = true,
    }, {}, {}, {}, function() p:resolve(true) end, function() p:resolve(false) end)
    return Citizen.Await(p)
end

Ahora tu script solo llama a Notify('Done', 'success') y Progress('Working', 5000). Si ox_lib está instalado, se usa primero. De lo contrario, se usa QBCore, y las notificaciones retroceden a ESX.

La barra de progreso de retroceso solo cubre QBCore. En un servidor sin ox_lib ni QBCore, añade tu propia rama o haz que ox_lib sea una dependencia requerida con dependency 'ox_lib'.

Consejo: haz lo mismo en el servidor con una función NotifyPlayer(source, message, type), usando las llamadas de servidor de las secciones anteriores. Luego ningún otro archivo necesita saber qué framework se ejecuta.

Lista de verificación

Síntoma Solución
attempt to index a nil value (global 'lib') Añade shared_script '@ox_lib/init.lua' e inicia ox_lib primero
La notificación del servidor no hace nada Dispara el evento del cliente con el source del jugador como segundo argumento
La notificación de QBCore no tiene color Usa un tipo válido: 'primary', 'success' o 'error'
La barra de progreso bloquea el resto de la función lib.progressBar espera: ejecútala en un hilo o controlador
El jugador puede caminar durante la barra Establece disable (ox_lib) o disableMovement (QBCore)
El script debe funcionar en ESX y QBCore Usa las funciones puente y llama solo a las que existen

Respuestas rápidas

¿Cómo envío una notificación desde el servidor?

En ESX usa xPlayer.showNotification(msg). En QBCore usa TriggerClientEvent('QBCore:Notify', source, msg, 'success'). Con ox_lib usa TriggerClientEvent('ox_lib:notify', source, { description = msg, type = 'success' }).

¿lib.progressBar bloquea el script?

Sí. Espera hasta que la barra termine y devuelve true, o false si el jugador la cancela. Ejecútalo en un hilo o un controlador de eventos, no en un lugar que no deba esperar.

¿Por qué lib es nil cuando llamo a lib.notify?

Tu manifest le falta shared_script '@ox_lib/init.lua', u ox_lib no se inició antes que tu recurso.

Scripts que evitan este problema

Quest CreatorUn editor visual de misiones y diálogos con NPC, nodo a nodo dentro del juego.Ver script →Advanced BoostingBoosting de vehículos desde una tablet: contratos de clase D a S+, crews y cola en vivo.Ver script →Mic PhoneUn móvil plegable que se abre en tablet y llega al móvil real del jugador.Ver script →

Sigue leyendo