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ì:
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:
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:
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:
-- 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:
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.luanel 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:
ensure oxmysql
ensure ox_lib
ensure es_extended
ensure [esx]
ensure my_scriptAltre due cose da controllare nella console del server, dall'alto:
- es_extended è stato avviato senza errori. Se fallisce (un
mysql_connection_stringerrato, 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:
-- 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.
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:
- Chiedi un aggiornamento al suo autore. Qualsiasi script ancora venduto per ESX dovrebbe utilizzare l'esportazione.
- Rispondi tu stesso al vecchio evento da ESX. In es_extended, aggiungi questo a un file del server e a un file del client:
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 →