ESX — это nil: исправление esx:getSharedObject в ESX Legacy
attempt to index a nil value (global 'ESX')? Старое событие esx:getSharedObject исчезло из ESX Legacy. Вот однострочное исправление и то, что делать со скриптами, которые вы не можете редактировать.
Вы запускаете свой сервер, открываете консоль F8 и вот оно:
SCRIPT ERROR: @my_script/client/main.lua:12: attempt to index a nil value (global 'ESX')Или серверный двойник attempt to index a nil value (upvalue 'ESX'). Сценарий в порядке, ESX работает, а ESX по-прежнему равен nil. Это самая распространенная ESX ошибка, и почти всегда она имеет одну и ту же причину.
Почему ESX — это nil
Старые сценарии ESX получают объект ESX следующим образом:
ESX = nil
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)В этом событии ESX 1.1 и 1.2 раздавали свой общий объект. ESX Legacy устарел, и текущие версии больше не отвечают на него. Сценарий запускает событие, никто не отвечает, и ESX остается nil до тех пор, пока первая строка, которая его использует, не выйдет из строя.
Вы увидите это в основном в сценариях, написанных много лет назад или скопированных из старых руководств.
Исправление: спросите es_extended напрямую
Замените эти строки экспортом, который ESX Legacy предоставляет:
ESX = exports['es_extended']:getSharedObject()Это работает одинаково и на клиенте, и на сервере. Сделайте это в каждом файле, который использует ESX. Если в сценарии также имеется такой цикл ожидания, удалите его; экспорт отвечает сразу:
-- old code: remove it
Citizen.CreateThread(function()
while ESX == nil do
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
Citizen.Wait(0)
end
end)Еще проще: imports.lua
es_extended отправляет вам небольшой файл, который настраивает ESX. Добавьте его в fxmanifest.lua:
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
shared_script '@es_extended/imports.lua'
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }Теперь каждый файл клиента и сервера имеет глобальный файл ESX, и на клиенте ESX.PlayerData остается в курсе изменений работы и денег игрока. Вы можете полностью удалить строки getSharedObject.
Совет: используйте один подход для каждого сценария. Либо экспорт в верхней части каждого файла, либо
imports.luaв манифесте; смешивание обоих работает, но это шум.
Все еще nil? Проверьте порядок старта
Если вы уже используете экспорт, а ESX по-прежнему имеет значение nil или вы получаете No such export getSharedObject in resource es_extended, сценарий запускается раньше es_extended. Ваш server.cfg определяет порядок:
ensure oxmysql
ensure ox_lib
ensure es_extended
ensure [esx]
ensure my_scriptЕще две вещи, которые нужно проверить в консоли сервера, сверху:
- es_extended запустился без ошибок. В случае сбоя (неправильный
mysql_connection_string, отсутствующий oxmysql) каждый скрипт, зависящий от него, также завершается сбоем. - На самом деле папка называется
es_extended. Переименованная или дублированная копия нарушает имя экспорта, а в Linux имя чувствительно к регистру.
Мы подробно рассмотрим эту ошибку в разделе Нет такого экспорта getSharedObject в ресурсе es_extended.
Данные игрока в клиенте
Старые скрипты также читают проигрыватель следующим образом:
-- old
ESX.GetPlayerData()
RegisterNetEvent('esx:playerLoaded')
AddEventHandler('esx:playerLoaded', function(xPlayer) PlayerData = xPlayer end)Это по-прежнему работает в ESX Legacy, с одной деталью: подождите, пока плеер загрузится, прежде чем читать задание или деньги при запуске.
CreateThread(function()
while not ESX.IsPlayerLoaded() do Wait(250) end
local job = ESX.GetPlayerData().job
print(('job: %s (%s)'):format(job.name, job.grade))
end)
RegisterNetEvent('esx:setJob', function(job)
-- the job changed: refresh whatever shows it
end)Благодаря imports.lua ESX.PlayerData.job будет оставаться актуальным для вас.
Скрипты, которые нельзя редактировать
Если сценарий депонирован (зашифрован) и по-прежнему использует старое событие, вы не можете изменить его код. В порядке предпочтения:
- Попросите его автора предоставить обновленную информацию. Любой сценарий, который все еще продается за ESX, должен использовать экспорт.
- Ответьте на старое событие от ESX самостоятельно. В es_extended добавьте это в файл сервера и в файл клиента:
AddEventHandler('esx:getSharedObject', function(cb)
cb(ESX)
end)Внимание: это патч для самого es_extended. При обновлении ESX он перезаписывается, поэтому вам придется добавлять его заново после каждого обновления. Используйте это как временную меру, а не как решение проблемы.
Краткий контрольный список
| Симптом | Исправить |
|---|---|
attempt to index a nil value (global 'ESX') |
Замените TriggerEvent('esx:getSharedObject'…) на exports['es_extended']:getSharedObject() |
| Все еще nil после изменения | Запустите es_extended перед сценарием в server.cfg |
No such export getSharedObject |
es_extended не запущен, произошел сбой или имеет другое имя |
ESX.PlayerData.job – nil при запуске |
Сначала подождите ESX.IsPlayerLoaded() |
| Сценарий депонирования со старым событием | Спросите автора; тем временем ответьте на событие от es_extended |
Короткие ответы
Почему ESX nil в моем скрипте?
Скрипт запрашивает ESX со старым вызовом TriggerEvent('esx:getSharedObject'), на который текущий ESX Legacy больше не отвечает. Замените его на ESX = exports['es_extended']:getSharedObject() или добавьте shared_script '@es_extended/imports.lua' в fxmanifest.
Нужно ли мне изменять файлы клиента и сервера?
Да. Каждому файлу, использующему ESX, нужен объект как на клиенте, так и на сервере. Строка imports.lua в fxmanifest охватывает все из них одновременно.
Что делать, если сценарий депонирован и я не могу его редактировать?
Сначала попросите автора обновленную информацию. В крайнем случае вы можете ответить на старое событие из es_extended, но вам придется добавлять его обратно каждый раз при обновлении ESX.
Скрипты без этой проблемы
Advanced BoostingУгон машин на заказ через планшет: контракты от класса D до S+, команды и живая очередь.Смотреть скрипт →
Item Creator V2Создавайте используемые предметы с анимациями, пропами, эффектами и не только — без кода.Смотреть скрипт →
Shop CreatorМагазин меньше чем за минуту — владельцы, сотрудники, сейфы и ограбления в комплекте.Смотреть скрипт →