ESX to nil: naprawianie esx:getSharedObject w ESX Legacy
attempt to index a nil value (global 'ESX')? Stare wydarzenie esx:getSharedObject zniknęło z ESX Legacy. Oto jednowierszowa poprawka i co zrobić ze skryptami, których nie można edytować.
Uruchamiasz serwer, otwierasz konsolę F8 i gotowe:
SCRIPT ERROR: @my_script/client/main.lua:12: attempt to index a nil value (global 'ESX')Lub bliźniak po stronie serwera, attempt to index a nil value (upvalue 'ESX'). Skrypt jest w porządku, ESX działa, a ESX nadal wynosi nil. Jest to najczęstszy błąd ESX i prawie zawsze ma tę samą przyczynę.
Dlaczego ESX to nil
Starsze skrypty ESX pobierają obiekt ESX w następujący sposób:
ESX = nil
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)To wydarzenie polegało na tym, jak ESX 1.1 i 1.2 przekazały swój wspólny obiekt. ESX Legacy zostało uznane za przestarzałe i obecne wersje już na to nie odpowiadają. Skrypt wyzwala zdarzenie, nikt nie odpowiada, a ESX pozostaje nil do czasu awarii pierwszej linii, która go używa.
Zobaczysz to głównie w przypadku skryptów napisanych wiele lat temu lub skopiowanych ze starych tutoriali.
Poprawka: zapytaj es_extended bezpośrednio
Zastąp te linie eksportem ESX Legacy, który zapewnia:
ESX = exports['es_extended']:getSharedObject()Działa tak samo na kliencie i na serwerze. Zrób to w każdym pliku, który używa ESX. Jeśli skrypt również zawierał pętlę oczekiwania taką jak ta, usuń ją; eksport odpowiada od razu:
-- old code: remove it
Citizen.CreateThread(function()
while ESX == nil do
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
Citizen.Wait(0)
end
end)Jeszcze prościej: imports.lua
es_extended dostarcza mały plik, który konfiguruje ESX za Ciebie. Dodaj go do fxmanifest.lua:
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
shared_script '@es_extended/imports.lua'
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }Teraz każdy plik klienta i serwera ma globalny ESX, a na kliencie ESX.PlayerData jest na bieżąco, gdy zmienia się praca gracza i pieniądze. Możesz całkowicie usunąć linie getSharedObject.
Wskazówka: użyj jednego podejścia na skrypt. Albo eksport na górze każdego pliku, albo
imports.luaw manifeście; miksowanie obu działa, ale jest to hałas.
Nadal nil? Sprawdź kolejność rozpoczęcia
Jeśli już korzystasz z eksportu i ESX nadal wynosi nil lub otrzymujesz No such export getSharedObject in resource es_extended, skrypt uruchamia się przed es_extended. Twoje server.cfg decyduje o kolejności:
ensure oxmysql
ensure ox_lib
ensure es_extended
ensure [esx]
ensure my_scriptJeszcze dwie rzeczy do sprawdzenia w konsoli serwera, od samej góry:
- es_extended uruchomił się bez błędów. Jeśli się nie powiedzie (złe
mysql_connection_string, brakujące oxmysql), każdy skrypt od niego zależny również zakończy się niepowodzeniem. - Folder tak naprawdę nazywa się
es_extended. Kopia o zmienionej nazwie lub zduplikowana powoduje uszkodzenie nazwy eksportu, a w systemie Linux w nazwie rozróżniana jest wielkość liter.
Szczegółowo omawiamy ten błąd w Brak takiego eksportu getSharedObject w zasobie es_extended.
Dane gracza w kliencie
Stare skrypty również czytają odtwarzacz w ten sposób:
-- old
ESX.GetPlayerData()
RegisterNetEvent('esx:playerLoaded')
AddEventHandler('esx:playerLoaded', function(xPlayer) PlayerData = xPlayer end)To nadal działa w ESX Legacy, z jednym szczegółem: poczekaj, aż odtwarzacz się załaduje, zanim zaczniesz czytać zlecenie lub pieniądze przy uruchomieniu.
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)Dzięki imports.lua wartość ESX.PlayerData.job jest dla Ciebie na bieżąco.
Skrypty, których nie można edytować
Jeśli skrypt jest zdeponowany (zaszyfrowany) i nadal korzysta ze starego zdarzenia, nie można zmienić jego kodu. W kolejności preferencji:
- Poproś autora o aktualizację. Każdy skrypt nadal sprzedawany za ESX powinien korzystać z eksportu.
- Odpowiedz samodzielnie na stare wydarzenie od ESX. W es_extended dodaj to do pliku serwera i pliku klienta:
AddEventHandler('esx:getSharedObject', function(cb)
cb(ESX)
end)Ostrzeżenie: to jest poprawka do samego es_extended. Aktualizacja ESX powoduje jego zastąpienie, dlatego po każdej aktualizacji należy go dodać ponownie. Zachowaj to jako rozwiązanie tymczasowe, a nie rozwiązanie.
Krótka lista kontrolna
| Objaw | Napraw |
|---|---|
attempt to index a nil value (global 'ESX') |
Zamień TriggerEvent('esx:getSharedObject'…) na exports['es_extended']:getSharedObject() |
| Nadal nil po zmianie | Rozpocznij es_extended przed skryptem w server.cfg |
No such export getSharedObject |
es_extended nie został uruchomiony, nie powiódł się lub ma inną nazwę |
ESX.PlayerData.job to nil podczas uruchamiania |
Najpierw poczekaj na ESX.IsPlayerLoaded() |
| Skrypt zdeponowany ze starym wydarzeniem | Zapytaj autora; w międzyczasie odpowiedz na wydarzenie z es_extended |
Szybkie odpowiedzi
Dlaczego w moim skrypcie znajduje się ESX nil?
Skrypt pyta o ESX starym wywołaniem TriggerEvent('esx:getSharedObject'), które obecne ESX Legacy już nie odpowiada. Zastąp go ESX = exports['es_extended']:getSharedObject() lub dodaj shared_script '@es_extended/imports.lua' do manifestu fx.
Czy muszę zmieniać pliki klienta i serwera?
Tak. Każdy plik używający ESX potrzebuje obiektu, zarówno na kliencie, jak i na serwerze. Wiersz imports.lua w manifeście fx obejmuje je wszystkie na raz.
Co się stanie, jeśli skrypt zostanie zdeponowany i nie będzie można go edytować?
Najpierw poproś autora o aktualizację. W ostateczności możesz odpowiedzieć na stare wydarzenie z es_extended, ale musisz to dodać ponownie przy każdej aktualizacji ESX.
Skrypty bez tego problemu
Advanced BoostingBoosting pojazdów z tabletu: kontrakty od klasy D do S+, ekipy i kolejka na żywo.Zobacz skrypt →
Item Creator V2Twórz używalne przedmioty z animacjami, propami, efektami i nie tylko — bez pisania kodu.Zobacz skrypt →
Shop CreatorZbuduj sklep w niecałą minutę — właściciele, pracownicy, sejfy i napady w zestawie.Zobacz skrypt →