aether-core: Netzwerk-Race beim Spawn beheben (Charakterauswahl-Crash)
Der Core schaltete Auto-Spawn ab, erzwang aber keinen kontrollierten Spawn und fasste den Ped sofort an. Dadurch lief die unkontrollierte Spawn-Erzeugung des spawnmanagers parallel zur Ped-Manipulation von Core/Character -> zwei Threads schrieben gleichzeitig Netz-State: "SendNetPacket called from multiple threads" -> Client-Crash beim Charaktermenue (schwarzer Bildschirm, dann Absturz). Fix: Auto-Spawn aus, EINMAL kontrolliert via spawnPlayer spawnen, auf den Callback warten und den Ped erst danach unsichtbar/geparkt setzen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
32879ac07b
commit
a5c517ff65
@ -19,18 +19,48 @@ CreateThread(function()
|
|||||||
Wait(100)
|
Wait(100)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Standard-Spawnverhalten von FiveM unterbinden.
|
-- Bildschirm sofort schwarz halten, bevor irgendetwas spawnt
|
||||||
-- Abgesichert, falls spawnmanager nicht laeuft (dann uebernimmt der Core allein).
|
DoScreenFadeOut(0)
|
||||||
local erfolg = pcall(function()
|
|
||||||
|
-- WICHTIG: den Spawn deterministisch selbst steuern.
|
||||||
|
-- Ohne einen kontrollierten Spawn liefert der spawnmanager den Ped
|
||||||
|
-- unkontrolliert (Auto-Spawn) — dann fasst der Core/Character-Flow den
|
||||||
|
-- Ped an, WÄHREND die Netzwerk-Erzeugung noch läuft. Zwei Threads
|
||||||
|
-- schreiben dann gleichzeitig Netz-State:
|
||||||
|
-- "SendNetPacket ... called from multiple threads" -> Client-Crash.
|
||||||
|
-- Lösung: Auto-Spawn AUS, EINMAL kontrolliert spawnen, und den Ped erst
|
||||||
|
-- NACH dem Spawn-Callback anfassen.
|
||||||
|
local spawnFertig = false
|
||||||
|
local hatSpawnmanager = pcall(function()
|
||||||
exports.spawnmanager:setAutoSpawn(false)
|
exports.spawnmanager:setAutoSpawn(false)
|
||||||
|
exports.spawnmanager:spawnPlayer({
|
||||||
|
x = Config.SpawnPunkt.x,
|
||||||
|
y = Config.SpawnPunkt.y,
|
||||||
|
z = Config.SpawnPunkt.z,
|
||||||
|
heading = Config.SpawnPunkt.heading or 0.0,
|
||||||
|
model = 'mp_m_freemode_01',
|
||||||
|
skipFade = true, -- wir steuern den Fade selbst
|
||||||
|
}, function()
|
||||||
|
spawnFertig = true
|
||||||
end)
|
end)
|
||||||
if not erfolg then
|
end)
|
||||||
|
|
||||||
|
if hatSpawnmanager then
|
||||||
|
-- Auf den Spawn-Callback warten (mit Sicherheitslimit ~5 s)
|
||||||
|
local versuche = 0
|
||||||
|
while not spawnFertig and versuche < 100 do
|
||||||
|
Wait(50)
|
||||||
|
versuche = versuche + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
Aether.Debug('spawnmanager nicht verfuegbar — Core spawnt eigenstaendig.')
|
Aether.Debug('spawnmanager nicht verfuegbar — Core spawnt eigenstaendig.')
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Bildschirm schwarz halten, bis der Charakter geladen ist
|
-- Jetzt existiert ein gültiger, gestreamter Ped. Erst JETZT anfassen:
|
||||||
DoScreenFadeOut(0)
|
-- unsichtbar und geparkt halten, bis der Charakter gewählt ist.
|
||||||
SetEntityVisible(PlayerPedId(), false, false)
|
local ped = PlayerPedId()
|
||||||
|
SetEntityVisible(ped, false, false)
|
||||||
|
FreezeEntityPosition(ped, true)
|
||||||
|
|
||||||
Aether.Debug('Client bereit — fordere Spielerdaten an.')
|
Aether.Debug('Client bereit — fordere Spielerdaten an.')
|
||||||
TriggerServerEvent('aether:server:spielerBereit')
|
TriggerServerEvent('aether:server:spielerBereit')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user