attempt to index a nil value (local 'Player'): QBCore ve QBox düzeltme

QBCore veya QBox betiğinizde Player nil mi? QBCore.Functions.GetPlayer(source) neden nil döndürür, citizenid aranması yalnızca çevrimiçi oyuncular ve güvenli koruma desenleri için.

Sunucu konsolunda:

text
SCRIPT ERROR: @my_script/server/main.lua:27: attempt to index a nil value (local 'Player')
lua
local Player = QBCore.Functions.GetPlayer(source)
Player.Functions.AddMoney('cash', 100)   -- Player is nil

GetPlayer bu kimlik için yüklü oyuncu bulamamış ve nil döndürmüş, sonraki satır onu indeksledi. Nedenler ESX durumunu ESX xPlayer is nil'de yansıtıyor, QBCore ve QBox özel özellikleriyle.

1. Oyuncu henüz yüklenmedi

Oyuncu, QBCore karakterlerini yüklenmeden önce bağlanabilir, özellikle multicharacter ekranı açıkken. Karakter seçilene kadar, GetPlayer(source) nil döndürür.

playerJoining'de çalışan veya hemen başlayan bir iş parçacığından kod bunu vurur. QBCore olayı bekleyin, bu olay oyuncu hazır olduğunda ateşlenir. Sunucuda:

lua
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
    print(Player.PlayerData.citizenid .. ' is loaded')
end)

İstemcide, eşleşen olay QBCore:Client:OnPlayerLoaded'dır:

lua
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
    PlayerLoaded = true
end)

Kaynağınız oyuncular çevrimiçiyken yeniden başlatılırsa, bu olaylar onlar için tekrar ateşlenmez. Başında, zaten yüklenen oyuncuların içinde gidin:

lua
CreateThread(function()
    for _, src in pairs(QBCore.Functions.GetPlayers()) do
        local Player = QBCore.Functions.GetPlayer(src)
        if Player then
            -- set up the player
        end
    end
end)

2. Wait sonrasında source değişti

source, çalışan olay için FiveM'nin ayarladığı genel bir değişkendir. İşleyicinin içinde Wait'i çağırırsanız, başka olay çalışabilir ve bunu değiştirebilir.

lua
RegisterNetEvent('my_script:sell', function()
    Wait(1000)
    local Player = QBCore.Functions.GetPlayer(source)   -- may be wrong, or nil
end)

Önce saklayın:

lua
RegisterNetEvent('my_script:sell', function()
    local src = source
    Wait(1000)

    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end
end)

3. Kimlik yanlış

GetPlayer bir çevrimiçi oyuncunun sunucu kimliğini, bir sayı olarak bekler.

  • Bir komuttan dize. Argümanlar metindir, bu nedenle dönüştürün: QBCore.Functions.GetPlayer(tonumber(args[1])).
  • İstemciden yanlış kimlik. İstemcide, PlayerId() yerel dizindir. Sunucu kimliği GetPlayerServerId(PlayerId())'dir. Daha iyi, istemci tarafından gönderilen kimlik yoksayın ve source'u kullanın, bkz. securing server events.
  • Konsol. Sunucu konsolunda yazılan komutun source 0'a eşittir, bu da oyuncu değildir.
  • Gitmiş bir kimlik. Oyuncu, kodunuz beklerken bağlantısı kesildi.
lua
QBCore.Commands.Add('givecash', 'Give cash', { { name = 'id', help = 'Player id' }, { name = 'amount', help = 'Amount' } }, true, function(source, args)
    local target = QBCore.Functions.GetPlayer(tonumber(args[1]))
    local amount = tonumber(args[2])
    if not target or not amount then return end

    target.Functions.AddMoney('cash', amount)
end, 'admin')

4. citizenid aramaları yalnızca çevrimiçi oyuncuları bulur

Birçok betik, kaynak her oturumda değiştiği için source yerine citizenid'i saklar. Oyuncuyu bir citizenid'den almak için:

lua
local Player = QBCore.Functions.GetPlayerByCitizenId(citizenid)

Bu yalnızca bu oyuncu çevrimiçi ve yüklü olduğunda çalışır. Çevrimdışı oyuncu için nil döndürür, bu verilerinizde hata değildir. Çevrimdışı oyuncuların veritabanını okuyun:

lua
local row = MySQL.single.await('SELECT charinfo, job FROM players WHERE citizenid = ?', { citizenid })
if row then
    local charinfo = json.decode(row.charinfo)
end

charinfo JSON metni olarak depolanır, bu nedenle onu güvenli bir şekilde çözeyin, bkz. FiveM json.decode errors. Çevrimdışı oyuncuya yazma farklı bir görevdir: oyuncu gerçekten çevrimdışı ise yalnızca veritabanı satırını değiştirin, yoksa sunucudan sonraki kayıt değişikliğinizi üzerine yazar.

5. QBox'ta

QBox'un çekirdeği qbx_core'dur. Uyumluluk katmanını tutar, bu nedenle QBCore.Functions.GetPlayer QBCore için yazılan betiklerde hala çalışır. Yeni kod için dışa aktarımlarını kullanın, bu da aynı türdeki oyuncu nesnesini veya nil'i döndürür:

lua
local player = exports.qbx_core:GetPlayer(source)
if not player then return end

print(player.PlayerData.citizenid)

Çevrimiçi oyuncu için citizenid tarafından:

lua
local player = exports.qbx_core:GetPlayerByCitizenId(citizenid)

Bu makaledir kural aynı şekilde uygulanır: karakter yüklenmeyene kadar oyuncu yok, bir Wait önce source'u saklayın ve çevrimdışı oyuncu için nil bekleyin. Betikleri çekirdekler arasında taşıyorsanız, converting a QBCore script to QBox bölümüne bakın.

6. playerDropped

Oyuncu ayrıldığında qb-core oyuncuyu kendi başına kaydeder ve kaldırır ve playerDropped için işleyicilerin sırası güvenilmesi gereken bir şey değildir. Kendi playerDropped işleyicisinde, GetPlayer(source) zaten nil olabilir. Oyuncu çevrimiçiyken ihtiyacınız olan her şeyi kendi tablonuzda tutun:

lua
local sessions = {}

AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
    sessions[Player.PlayerData.source] = Player.PlayerData.citizenid
end)

AddEventHandler('playerDropped', function()
    local citizenid = sessions[source]
    sessions[source] = nil
    if citizenid then
        print(citizenid .. ' left')
    end
end)

Koruma deseni

Oyuncu gereksinim her sunucu işleyicisini aynı şekilde başlatın:

lua
RegisterNetEvent('my_script:action', function()
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end

    -- Player is safe to use here
end)

İpucu: hata QBCore'ın kendisinin nil olduğundan ise, sorun çekirdek nesnesidir, oyuncu değil. Bkz. attempt to index a nil value (global 'QBCore').

Kontrol listesi

Belirtisi Çözüm
Oyuncu katıldıktan hemen sonra nil playerJoining yerine QBCore:Server:PlayerLoaded bekleyin
Bir Wait sonrasında nil local src = source saklayın ve src kullanın
Bir komuttan nil Argümanı tonumber ile dönüştürün; konsol source'u 0
GetPlayerByCitizenId nil döndürür Oyuncu çevrimdışı; players tablosunu sorgulayın
QBox sunucu exports.qbx_core:GetPlayer(source) kullanın ve nil kontrol edin
playerDropped'da nil Oyuncu çevrimiçiyken ihtiyacınız olan veriyi kendi tablonuzda tutun
Herhangi nil İşleyicinin başına if not Player then return end ekleyin

Kısa yanıtlar

QBCore.Functions.GetPlayer neden nil döndürür?

Bu kimlikte yüklü oyuncu yok. Oyuncu hala yüklenebilir, kimlik yanlış veya bir Wait sonrasında kaybolabilir veya oyuncu zaten gitti.

GetPlayerByCitizenId çevrimdışı oyuncular için çalışır mı?

Hayır. Yalnızca çevrimiçi oyuncuları bulur. Çevrimdışı oyuncu için bunun yerine veritabanında players tablosunu okuyun.

QBox'un QBCore.Functions.GetPlayer'ın eşdeğeri nedir?

exports.qbx_core:GetPlayer(source). Bu kimlik için yüklü oyuncu olduğunda oyuncu nesnesini veya nil'i döndürür.

Bu sorunu yaşatmayan scriptler

Advanced BoostingTabletten araç boosting: D’den S+ sınıfına kontratlar, ekipler ve canlı sıra.Scripti gör →Drug Dealer Applb-phone uygulaması olarak sokak satışı: bölgeler, NPC alıcılar, seviyeler ve polis ihbarları.Scripti gör →Pawn Shop Applb-phone içinde oyuncudan oyuncuya rehin pazarı.Scripti gör →

Okumaya devam edin