ESX est nil : correction de esx:getSharedObject dans ESX Legacy

attempt to index a nil value (global 'ESX') ? L’ancien événement esx:getSharedObject a disparu de ESX Legacy. Voici le correctif en une ligne et que faire avec les scripts que vous ne pouvez pas modifier.

Vous démarrez votre serveur, ouvrez la console F8 et voilà :

text
SCRIPT ERROR: @my_script/client/main.lua:12: attempt to index a nil value (global 'ESX')

Ou le jumeau côté serveur, attempt to index a nil value (upvalue 'ESX'). Le script fonctionne bien, ESX est en cours d'exécution et ESX est toujours nil. Il s'agit de l'erreur ESX la plus courante, et elle a presque toujours la même cause.

Pourquoi ESX est nil

Les anciens scripts ESX obtiennent l'objet ESX comme ceci :

lua
ESX = nil

TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)

Cet événement a permis à ESX 1.1 et 1.2 de distribuer leur objet partagé. ESX Legacy l'a rendu obsolète et les versions actuelles n'y répondent plus. Le script déclenche l'événement, personne ne répond et ESX reste nil jusqu'à ce que la première ligne qui l'utilise plante.

Vous verrez cela principalement avec des scripts écrits il y a des années ou copiés à partir d'anciens tutoriels.

La solution : demandez es_extended directement

Remplacez ces lignes par l'export ESX Legacy fournit :

lua
ESX = exports['es_extended']:getSharedObject()

Cela fonctionne de la même manière sur le client et sur le serveur. Faites-le dans chaque fichier qui utilise ESX. Si le script comportait également une boucle d'attente comme celle-ci, supprimez-la ; l'export répond tout de suite :

lua
-- old code: remove it
Citizen.CreateThread(function()
    while ESX == nil do
        TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
        Citizen.Wait(0)
    end
end)

Encore plus simple : imports.lua

es_extended fournit un petit fichier qui configure ESX pour vous. Ajoutez-le au fxmanifest.lua du script :

lua
fx_version 'cerulean'
game 'gta5'
lua54 'yes'

shared_script '@es_extended/imports.lua'

client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }

Désormais, chaque fichier client et serveur possède un ESX global, et sur le client, ESX.PlayerData reste à jour à mesure que le travail et l'argent du joueur changent. Vous pouvez supprimer entièrement les getSharedObject lignes.

Astuce: utilisez une approche par script. Soit l'export en haut de chaque fichier, soit imports.lua dans le manifeste ; mélanger les deux fonctionne, mais c'est du bruit.

Toujours nil ? Vérifiez l'ordre de départ

Si vous utilisez déjà l'exportation et que ESX est toujours nil, ou que vous obtenez No such export getSharedObject in resource es_extended, le script démarre avant es_extended. Votre server.cfg décide de la commande :

cfg
ensure oxmysql
ensure ox_lib
ensure es_extended
ensure [esx]

ensure my_script

Deux autres choses à vérifier dans la console du serveur, tout en haut :

  • es_extended a démarré sans erreur. S'il échoue (un mauvais mysql_connection_string, un oxmysql manquant), tous les scripts qui en dépendent échouent également.
  • Le dossier s'appelle en réalité es_extended. Une copie renommée ou dupliquée rompt le nom d'exportation, et sous Linux, le nom est sensible à la casse.

Nous examinons cette erreur en détail dans Aucune exportation de ce type getSharedObject dans la ressource es_extended.

Données du joueur sur le client

Les anciens scripts lisaient également le lecteur comme ceci :

lua
-- old
ESX.GetPlayerData()
RegisterNetEvent('esx:playerLoaded')
AddEventHandler('esx:playerLoaded', function(xPlayer) PlayerData = xPlayer end)

Cela fonctionne toujours sous ESX Legacy, avec un détail : attendez que le lecteur soit chargé avant de lire le job ou l'argent au démarrage.

lua
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)

Avec imports.lua, ESX.PlayerData.job reste à jour pour vous.

Scripts que vous ne pouvez pas modifier

Si le script est déposé (crypté) et utilise toujours l'ancien événement, vous ne pouvez pas modifier son code. Par ordre de préférence :

  1. Demandez une mise à jour à son auteur. Tout script encore vendu pour ESX devrait utiliser l'export.
  2. Répondez vous-même à l'ancien événement de ESX. Dans es_extended, ajoutez ceci à un fichier serveur et à un fichier client :
lua
AddEventHandler('esx:getSharedObject', function(cb)
    cb(ESX)
end)

Attention: il s'agit d'un correctif pour es_extended lui-même. La mise à jour de ESX l'écrase, vous devez donc l'ajouter à nouveau après chaque mise à jour. Conservez-le comme un pis-aller, pas comme une solution.

Liste de contrôle rapide

Symptôme Corriger
attempt to index a nil value (global 'ESX') Remplacez TriggerEvent('esx:getSharedObject'…) par exports['es_extended']:getSharedObject()
Toujours nil après le changement Démarrer es_extended avant le script dans server.cfg
No such export getSharedObject es_extended n'a pas démarré, a échoué ou est nommé différemment
ESX.PlayerData.job est nil au démarrage Attendez ESX.IsPlayerLoaded() d'abord
Script déposé avec l'ancien événement Demandez à l'auteur ; pendant ce temps, répondez à l'événement de es_extended

Réponses rapides

Pourquoi ESX nil dans mon script ?

Le script demande ESX avec l'ancien appel TriggerEvent('esx:getSharedObject'), auquel le ESX Legacy actuel ne répond plus. Remplacez-le par ESX = exports['es_extended']:getSharedObject() ou ajoutez shared_script '@es_extended/imports.lua' au fxmanifest.

Dois-je modifier les fichiers client et serveur ?

Oui. Chaque fichier qui utilise ESX a besoin de l'objet, sur le client et sur le serveur. La ligne imports.lua du fxmanifest les couvre tous à la fois.

Que faire si le script est déposé et que je ne peux pas le modifier ?

Demandez d'abord une mise à jour à son auteur. En dernier recours, vous pouvez répondre à l'ancien événement à partir de es_extended, mais vous devez le rajouter à chaque fois que vous mettez à jour ESX.

Des scripts sans ce problème

Advanced BoostingDu boosting de véhicules piloté par tablette : contrats de classe D à S+, crews et file d’attente en direct.Voir le script →Item Creator V2Créez des items utilisables avec animations, props, effets et plus — sans écrire une ligne de code.Voir le script →Shop CreatorCréez un magasin en moins d’une minute — propriétaires, employés, coffres et braquages inclus.Voir le script →

À lire aussi