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:
SCRIPT ERROR: @my_script/server/main.lua:27: attempt to index a nil value (local 'Player')local Player = QBCore.Functions.GetPlayer(source)
Player.Functions.AddMoney('cash', 100) -- Player is nilGetPlayer 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:
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
print(Player.PlayerData.citizenid .. ' is loaded')
end)İstemcide, eşleşen olay QBCore:Client:OnPlayerLoaded'dır:
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:
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.
RegisterNetEvent('my_script:sell', function()
Wait(1000)
local Player = QBCore.Functions.GetPlayer(source) -- may be wrong, or nil
end)Önce saklayın:
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ğiGetPlayerServerId(PlayerId())'dir. Daha iyi, istemci tarafından gönderilen kimlik yoksayın vesource'u kullanın, bkz. securing server events. - Konsol. Sunucu konsolunda yazılan komutun
source0'a eşittir, bu da oyuncu değildir. - Gitmiş bir kimlik. Oyuncu, kodunuz beklerken bağlantısı kesildi.
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:
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:
local row = MySQL.single.await('SELECT charinfo, job FROM players WHERE citizenid = ?', { citizenid })
if row then
local charinfo = json.decode(row.charinfo)
endcharinfo 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:
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:
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:
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:
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 →