Уведомления и полосы прогресса FiveM: ESX, QBCore и ox_lib

Отправляйте уведомления и показывайте полосы прогресса на ESX, QBCore и ox_lib с помощью ShowNotification, Functions.Notify, lib.notify и lib.progressBar, плюс одна функция моста.

Каждый фреймворк имеет свой способ показать сообщение или полосу прогресса, и скрипт, написанный для одного, не работает на другом:

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

Эта статья содержит вызовы для ESX, QBCore и ox_lib для уведомлений и полос прогресса, затем показывает одну функцию моста, чтобы ваш скрипт работал на том, что запущено на сервере.

Уведомления на ESX

На клиенте:

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

На сервере от объекта игрока:

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

ESX здесь — это объект из ESX = exports['es_extended']:getSharedObject(). Недавние версии ESX также принимают тип и продолжительность после текста. Если вы на них полагаетесь, проверьте вашу версию.

Уведомления на QBCore

На клиенте:

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

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

Тип — это 'primary', 'success' или 'error', а последнее значение — это время в миллисекундах. С сервера отправьте событие игроку:

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

На QBox те же вызовы QBCore продолжают работать через его слой совместимости, и уведомления ox_lib — это хорошая альтернатива.

Уведомления с ox_lib

ox_lib имеет своё уведомление, и оно работает одинаково на каждом фреймворке. На клиенте:

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

Тип — это 'inform', 'success', 'warning' или 'error'. С сервера запустите событие на игроке:

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

Глобальное lib требует shared_script '@ox_lib/init.lua' в вашем fxmanifest.lua, как описано в руководстве по контекстному меню ox_lib. Без него вы получите ошибку lib nil выше.

Полосы прогресса

С ox_lib полоса прогресса — это вызов, который ждёт и возвращает, закончилась ли она:

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 принимает те же параметры и показывает круг вместо полосы. Оба также могут прикрепить prop к игроку.

Версия QBCore использует обратный вызов вместо ожидания:

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)

Аргументы в порядке: имя, метка, продолжительность, useWhileDead, canCancel, отключенные элементы управления, анимация, два prop, затем обратные вызовы завершения и отмены. ESX не имеет своей полосы прогресса, которую все серверы используют, поэтому на ESX используйте lib.progressBar.

Одна функция моста для всех них

Чтобы сохранить независимость ваших скриптов от фреймворка, напишите детали фреймворка один раз и вызывайте свои собственные функции везде. Поместите это в файл клиента:

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

Теперь ваш скрипт только вызывает Notify('Done', 'success') и Progress('Working', 5000). Если установлен ox_lib, он используется в первую очередь. В противном случае используется QBCore, и уведомления переходят на ESX.

Полоса прогресса резервного варианта охватывает только QBCore. На сервере без ox_lib и QBCore добавьте собственную ветку или сделайте ox_lib требуемой зависимостью с dependency 'ox_lib'.

Совет: сделайте то же самое на сервере с одной функцией NotifyPlayer(source, message, type), используя вызовы сервера из разделов выше. Тогда никакому другому файлу не нужно знать, какой фреймворк запущен.

Контрольный список

Симптом Решение
attempt to index a nil value (global 'lib') Добавьте shared_script '@ox_lib/init.lua' и запустите ox_lib первым
Уведомление сервера ничего не делает Запустите событие клиента с source игрока в качестве второго аргумента
Уведомление QBCore не имеет цвета Используйте допустимый тип: 'primary', 'success' или 'error'
Полоса прогресса блокирует остальную часть функции lib.progressBar ждёт: запустите его в потоке или обработчике
Игрок может ходить во время полосы Установите disable (ox_lib) или disableMovement (QBCore)
Скрипт должен работать на ESX и QBCore Используйте функции моста и вызывайте только их

Короткие ответы

Как отправить уведомление с сервера?

На ESX используйте xPlayer.showNotification(msg). На QBCore используйте TriggerClientEvent('QBCore:Notify', source, msg, 'success'). С ox_lib используйте TriggerClientEvent('ox_lib:notify', source, { description = msg, type = 'success' }).

Блокирует ли lib.progressBar скрипт?

Да. Он ждёт, пока полоса закончится и возвращает true, или false, если игрок отменил. Запустите его в потоке или обработчике событий, а не в месте, которое не должно ждать.

Почему lib равен nil, когда я вызываю lib.notify?

В вашем манифесте отсутствует shared_script '@ox_lib/init.lua', или ox_lib не запущен перед вашим ресурсом.

Скрипты без этой проблемы

Quest CreatorВизуальный редактор квестов и диалогов с NPC — узел за узлом прямо в игре.Смотреть скрипт →Advanced BoostingУгон машин на заказ через планшет: контракты от класса D до S+, команды и живая очередь.Смотреть скрипт →Mic PhoneСкладной телефон, который раскладывается в планшет и работает и на настоящем телефоне игрока.Смотреть скрипт →

Читайте также