ESX ist nil: Fixierung von esx:getSharedObject in ESX Legacy

attempt to index a nil value (global 'ESX')? Das alte esx:getSharedObject-Ereignis ist aus ESX Legacy verschwunden. Hier ist die einzeilige Lösung und was mit Skripten zu tun ist, die Sie nicht bearbeiten können.

Sie starten Ihren Server, öffnen die F8-Konsole und da ist es:

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

Oder der serverseitige Zwilling, attempt to index a nil value (upvalue 'ESX'). Das Skript ist in Ordnung, ESX wird ausgeführt und ESX ist immer noch nil. Dies ist der häufigste ESX Fehler, den es gibt, und er hat fast immer die gleiche Ursache.

Warum ESX nil

Ältere ESX-Skripte erhalten das ESX-Objekt wie folgt:

lua
ESX = nil

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

Dieses Ereignis war die Art und Weise, wie ESX 1.1 und 1.2 ihr gemeinsames Objekt verteilten. ESX Legacy hat es als veraltet markiert und aktuelle Versionen antworten nicht mehr darauf. Das Skript löst das Ereignis aus, niemand antwortet und ESX bleibt nil, bis die erste Zeile, die es verwendet, abstürzt.

Sie werden dies meist bei Skripten sehen, die vor Jahren geschrieben oder aus alten Tutorials kopiert wurden.

Die Lösung: Fragen Sie es_extended direkt

Ersetzen Sie diese Zeilen durch den Export, den ESX Legacy bereitstellt:

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

Es funktioniert auf dem Client und auf dem Server gleich. Machen Sie es in jeder Datei, die ESX verwendet. Wenn das Skript auch eine Warteschleife wie diese hatte, löschen Sie diese; Der Export antwortet sofort:

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)

Noch einfacher: imports.lua

es_extended liefert eine kleine Datei, die ESX für Sie einrichtet. Fügen Sie es zum fxmanifest.lua:

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

shared_script '@es_extended/imports.lua'

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

Jetzt verfügt jede Client- und Serverdatei über ein globales ESX und auf dem Client bleibt ESX.PlayerData auf dem neuesten Stand, wenn sich der Job und das Geld des Spielers ändern. Sie können die Zeilen getSharedObject vollständig löschen.

Tipp: Verwenden Sie einen Ansatz pro Skript. Entweder der Export oben in jeder Datei oder imports.lua im Manifest; Beides zu mischen funktioniert, aber es ist Lärm.

Immer noch nil? Überprüfen Sie die Startreihenfolge

Wenn Sie den Export bereits verwenden und ESX immer noch nil ist oder Sie No such export getSharedObject in resource es_extended erhalten, startet das Skript vor es_extended. Ihr server.cfg entscheidet über die Reihenfolge:

cfg
ensure oxmysql
ensure ox_lib
ensure es_extended
ensure [esx]

ensure my_script

Zwei weitere Dinge, die Sie in der Serverkonsole überprüfen sollten, von ganz oben:

  • es_extended ohne Fehler gestartet. Wenn es fehlschlägt (ein fehlerhaftes mysql_connection_string, ein fehlendes oxmysql), schlägt auch jedes davon abhängige Skript fehl.
  • Der Ordner heißt eigentlich es_extended. Eine umbenannte oder duplizierte Kopie unterbricht den Exportnamen, und unter Linux wird beim Namen zwischen Groß- und Kleinschreibung unterschieden.

Wir gehen diesen Fehler im Detail unter Kein solcher Export getSharedObject in Ressource es_extended.

Spielerdaten auf dem Client

Alte Skripte lesen den Player auch so:

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

Das funktioniert immer noch in ESX Legacy, mit einem Detail: Warten Sie, bis der Player geladen ist, bevor Sie beim Start Job oder Geld lesen.

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)

Mit imports.lua wird ESX.PlayerData.job für Sie aktuell gehalten.

Skripte, die Sie nicht bearbeiten können

Wenn das Skript treuhänderisch (verschlüsselt) ist und immer noch das alte Ereignis verwendet, können Sie seinen Code nicht ändern. In der Reihenfolge Ihrer Präferenz:

  1. Bitten Sie den Autor um ein Update. Jedes Skript, das noch für ESX verkauft wird, sollte den Export verwenden.
  2. Beantworten Sie das alte Ereignis von ESX selbst. Fügen Sie dies in es_extended einer Serverdatei und einer Clientdatei hinzu:
lua
AddEventHandler('esx:getSharedObject', function(cb)
    cb(ESX)
end)

Achtung: Dies ist ein Patch für es_extended selbst. Durch das Aktualisieren von ESX wird es überschrieben, sodass Sie es nach jedem Update erneut hinzufügen müssen. Behalten Sie es als Notlösung, nicht als Lösung.

Schnelle Checkliste

Symptom Behebung
attempt to index a nil value (global 'ESX') Ersetzen Sie TriggerEvent('esx:getSharedObject'…) durch exports['es_extended']:getSharedObject()
Immer noch nil nach der Änderung Starten Sie es_extended vor dem Skript in server.cfg
No such export getSharedObject es_extended wurde nicht gestartet, ist fehlgeschlagen oder hat einen anderen Namen
ESX.PlayerData.job ist beim Start nil Warten Sie zuerst auf ESX.IsPlayerLoaded()
Skript mit dem alten Ereignis hinterlegt Fragen Sie den Autor; Beantworten Sie in der Zwischenzeit das Ereignis von es_extended

Kurze Antworten

Warum steht ESX nil in meinem Skript?

Das Skript fragt nach ESX mit dem alten TriggerEvent('esx:getSharedObject')-Anruf, der mit dem aktuellen ESX Legacy nicht mehr antwortet. Ersetzen Sie es durch ESX = exports['es_extended']:getSharedObject() oder fügen Sie shared_script '@es_extended/imports.lua' zum fxmanifest hinzu.

Muss ich sowohl Client- als auch Serverdateien ändern?

Ja. Jede Datei, die ESX verwendet, benötigt das Objekt, sowohl auf dem Client als auch auf dem Server. Die Zeile imports.lua im fxmanifest deckt alle auf einmal ab.

Was passiert, wenn das Skript hinterlegt ist und ich es nicht bearbeiten kann?

Bitten Sie zuerst den Autor um ein Update. Als letzten Ausweg können Sie auf das alte Ereignis von es_extended antworten, müssen es aber jedes Mal wieder hinzufügen, wenn Sie ESX aktualisieren.

Scripts ohne dieses Problem

Advanced BoostingFahrzeug-Boosting per Tablet: Aufträge von Klasse D bis S+, Crews und eine Live-Warteschlange.Script ansehen →Item Creator V2Erstelle nutzbare Items mit Animationen, Props, Effekten und mehr — ganz ohne Code.Script ansehen →Shop CreatorBau einen Shop in unter einer Minute — Besitzer, Angestellte, Tresore und Überfälle inklusive.Script ansehen →

Weiterlesen