ESX è nil: correggere esx:getSharedObject in ESX Legacy

attempt to index a nil value (global 'ESX')? Il vecchio evento esx:getSharedObject è scomparso da ESX Legacy. Ecco la soluzione in una riga e cosa fare con gli script che non puoi modificare.

Avvii il tuo server, apri la console F8 ed eccola lì:

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

O il gemello lato server, attempt to index a nil value (upvalue 'ESX'). Lo script va bene, ESX è in esecuzione e ESX è ancora nil. Questo è l'errore ESX più comune e ha quasi sempre la stessa causa.

Perché ESX è nil

Gli script ESX meno recenti ottengono l'oggetto ESX in questo modo:

lua
ESX = nil

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

Quell'evento è stato il modo in cui ESX 1.1 e 1.2 hanno distribuito il loro oggetto condiviso. ESX Legacy lo ha deprecato e le versioni attuali non rispondono più. Lo script attiva l'evento, nessuno risponde e ESX rimane nil finché la prima riga che lo utilizza non si arresta in modo anomalo.

Lo vedrai principalmente con script scritti anni fa o copiati da vecchi tutorial.

La soluzione: chiedi direttamente a es_extended

Sostituisci queste righe con l'esportazione ESX Legacy fornisce:

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

Funziona allo stesso modo sul client e sul server. Fallo in ogni file che utilizza ESX. Se anche lo script presenta un ciclo di attesa come questo, eliminalo; l'esportazione risponde subito:

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)

Ancora più semplice: imports.lua

es_extended invia un piccolo file che configura ESX per te. Aggiungilo al fxmanifest.lua:

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

shared_script '@es_extended/imports.lua'

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

Ora ogni file client e server ha un ESX globale e sul client ESX.PlayerData rimane aggiornato man mano che il lavoro e il denaro del giocatore cambiano. Puoi eliminare completamente le getSharedObject righe.

Suggerimento: utilizza un approccio per script. L'esportazione nella parte superiore di ogni file o imports.lua nel manifest; mescolare entrambi funziona, ma è rumore.

Ancora nil? Controlla l'ordine di partenza

Se usi già l'esportazione e ESX è ancora nil, o ottieni No such export getSharedObject in resource es_extended, lo script inizia prima es_extended. Il tuo server.cfg decide l'ordine:

cfg
ensure oxmysql
ensure ox_lib
ensure es_extended
ensure [esx]

ensure my_script

Altre due cose da controllare nella console del server, dall'alto:

  • es_extended è stato avviato senza errori. Se fallisce (un mysql_connection_string errato, un oxmysql mancante), anche ogni script che dipende da esso fallisce.
  • La cartella in realtà si chiama es_extended. Una copia rinominata o duplicata interrompe il nome di esportazione e su Linux il nome fa distinzione tra maiuscole e minuscole.

Esaminiamo questo errore in dettaglio in Nessuna esportazione di questo tipo getSharedObject nella risorsa es_extended.

Dati del giocatore sul client

Anche i vecchi script leggono il player in questo modo:

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

Funziona ancora in ESX Legacy, con un dettaglio: attendi che il lettore venga caricato prima di leggere lavoro o denaro all'avvio.

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)

Con imports.lua, ESX.PlayerData.job è sempre aggiornato per te.

Script che non puoi modificare

Se lo script è depositato in deposito (crittografato) e utilizza ancora il vecchio evento, non è possibile modificarne il codice. In ordine di preferenza:

  1. Chiedi un aggiornamento al suo autore. Qualsiasi script ancora venduto per ESX dovrebbe utilizzare l'esportazione.
  2. Rispondi tu stesso al vecchio evento da ESX. In es_extended, aggiungi questo a un file del server e a un file del client:
lua
AddEventHandler('esx:getSharedObject', function(cb)
    cb(ESX)
end)

Attenzione: questa è una patch per es_extended stesso. L'aggiornamento di ESX lo sovrascrive, quindi devi aggiungerlo di nuovo dopo ogni aggiornamento. Mantienilo come un toccasana, non come una soluzione.

Elenco di controllo rapido

Sintomo Correggi
attempt to index a nil value (global 'ESX') Sostituisci TriggerEvent('esx:getSharedObject'…) con exports['es_extended']:getSharedObject()
Ancora nil dopo la modifica Inizia es_extended prima dello script in server.cfg
No such export getSharedObject es_extended non è stato avviato, non è riuscito o ha un nome diverso
ESX.PlayerData.job è nil all'avvio Attendi prima ESX.IsPlayerLoaded()
Script depositato in deposito con il vecchio evento Chiedi all'autore; nel frattempo rispondi all'evento da es_extended

Risposte rapide

Perché ESX nil nel mio script?

Lo script richiede ESX con la vecchia chiamata TriggerEvent('esx:getSharedObject'), alla quale l'attuale ESX Legacy non risponde più. Sostituiscilo con ESX = exports['es_extended']:getSharedObject() o aggiungi shared_script '@es_extended/imports.lua' al fxmanifest.

Devo modificare sia i file client che quelli server?

Sì. Ogni file che utilizza ESX necessita dell'oggetto, sul client e sul server. La riga imports.lua nel fxmanifest li copre tutti contemporaneamente.

Cosa succede se lo script è depositato in garanzia e non posso modificarlo?

Chiedi prima un aggiornamento al suo autore. Come ultima risorsa puoi rispondere al vecchio evento da es_extended, ma devi aggiungerlo ogni volta che aggiorni ESX.

Script senza questo problema

Advanced BoostingBoosting di veicoli dal tablet: contratti dalla classe D alla S+, crew e coda in tempo reale.Vedi script →Item Creator V2Crea oggetti utilizzabili con animazioni, props, effetti e altro — senza scrivere codice.Vedi script →Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →

Continua a leggere