From 32879ac07bb2222f956c716cee5985150b11e4f5 Mon Sep 17 00:00:00 2001 From: Jerrit Fritzsche Date: Mon, 27 Jul 2026 19:36:38 +0200 Subject: [PATCH] aether-admin: Netzwerk-Race beim Join beheben MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Client-Threads (Positions-Meldung, Wetter/Zeit) liefen ab Resource- Start ungebremst — also schon während Ladebildschirm/Charakterauswahl, bevor der Spieler gespawnt ist. Zusammen mit den Server-Events der Character-NUI (eigener Thread) führte das zu gleichzeitigen Netz-Sends: "SendNetPacket called from multiple threads" -> Client-Crash. Fix: Nichts Vernetztes vor 'aether:client:bereit' (Spieler geladen). Weltzustand wird beim Spawn einmalig angewandt. Co-Authored-By: Claude Opus 4.8 --- .../[aether]/aether-admin/client/main.lua | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/resources/[aether]/aether-admin/client/main.lua b/resources/[aether]/aether-admin/client/main.lua index 3499abc..494adb4 100644 --- a/resources/[aether]/aether-admin/client/main.lua +++ b/resources/[aether]/aether-admin/client/main.lua @@ -9,6 +9,15 @@ local istOffen = false local darfPanel = false -- vom Server bestätigt +local geladen = false -- Spieler ist fertig geladen und gespawnt + +-- Erst wenn der Core den Spieler gespawnt hat, darf dieser Client etwas +-- Vernetztes tun. Vorher (Ladebildschirm/Charakterauswahl) würden Netz- +-- Sends aus Hintergrund-Threads mit dem Spawn kollidieren +-- ("SendNetPacket called from multiple threads"). +AddEventHandler('aether:client:bereit', function() + geladen = true +end) -- --------------------------------------------------------------------- -- Hilfen @@ -239,24 +248,36 @@ end local welt = { stunde = 12, minute = 0, wetter = 'CLEAR', zeitFix = false, wetterFix = false, blackout = false } +--- Weltzustand merken. Angewandt wird er erst, wenn der Spieler im Spiel ist +--- (sonst kollidiert das Wetter-Native mit dem Spawn). RegisterNetEvent('aether-admin:client:welt', function(neu) if type(neu) ~= 'table' then return end welt = neu + if geladen then + SetWeatherTypeOverTime(welt.wetter, 15.0) + SetArtificialLightsState(welt.blackout and true or false) + end +end) + +-- Beim Laden den zwischengespeicherten Weltzustand einmalig anwenden +AddEventHandler('aether:client:bereit', function() SetWeatherTypeOverTime(welt.wetter, 15.0) SetArtificialLightsState(welt.blackout and true or false) end) CreateThread(function() while true do - Wait(welt.zeitFix and 0 or 2000) - if welt.zeitFix then - NetworkOverrideClockTime(welt.stunde, welt.minute, 0) - end - if welt.wetterFix then - SetWeatherTypeNow(welt.wetter) - end - if welt.blackout then - SetArtificialLightsState(true) + Wait(geladen and welt.zeitFix and 0 or 2000) + if geladen then + if welt.zeitFix then + NetworkOverrideClockTime(welt.stunde, welt.minute, 0) + end + if welt.wetterFix then + SetWeatherTypeNow(welt.wetter) + end + if welt.blackout then + SetArtificialLightsState(true) + end end end end) @@ -267,8 +288,11 @@ end) CreateThread(function() while true do Wait(3000) - local pos = GetEntityCoords(PlayerPedId()) - TriggerServerEvent('aether-admin:pos', { x = pos.x, y = pos.y, z = pos.z }) + -- Erst melden, wenn der Spieler wirklich im Spiel ist + if geladen then + local pos = GetEntityCoords(PlayerPedId()) + TriggerServerEvent('aether-admin:pos', { x = pos.x, y = pos.y, z = pos.z }) + end end end)