From e403acf7442ed1ebdf142f2fddc35bc25f698fc2 Mon Sep 17 00:00:00 2001 From: NebelRebell <40825041+NebelRebell@users.noreply.github.com> Date: Sun, 22 Feb 2026 15:13:53 +0100 Subject: [PATCH] fix(client): prevent native crash in RaycastCamera Adds proper entity validation to prevent native crashes caused by invalid entity handles. - Validates entityHit against 0 and -1 - Uses DoesEntityExist before native calls - Fixes parameter order in HasEntityClearLosToEntity - Adds safe fallback for entityType == 0 Tested and verified on FiveM game build 2944. --- client.lua | 95 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/client.lua b/client.lua index 17a1475..4764c8b 100644 --- a/client.lua +++ b/client.lua @@ -100,36 +100,87 @@ local function DrawTarget() end) end -local function RaycastCamera(flag, playerCoords) - if not playerPed then playerPed = PlayerPedId() end - if not playerCoords then playerCoords = GetEntityCoords(playerPed) end +---NEBELBANK.net fix RaycastCamera-Error +-- local function RaycastCamera(flag, playerCoords) + -- if not playerPed then playerPed = PlayerPedId() end + -- if not playerCoords then playerCoords = GetEntityCoords(playerPed) end - local rayPos, rayDir = ScreenPositionToCameraRay() - local destination = rayPos + 16 * rayDir - local rayHandle = StartShapeTestLosProbe(rayPos.x, rayPos.y, rayPos.z, destination.x, destination.y, destination.z, - flag or -1, playerPed, 4) + -- local rayPos, rayDir = ScreenPositionToCameraRay() + -- local destination = rayPos + 16 * rayDir + -- local rayHandle = StartShapeTestLosProbe(rayPos.x, rayPos.y, rayPos.z, destination.x, destination.y, destination.z, + -- flag or -1, playerPed, 4) - while true do - local result, _, endCoords, _, entityHit = GetShapeTestResult(rayHandle) + -- while true do + -- local result, _, endCoords, _, entityHit = GetShapeTestResult(rayHandle) - if result ~= 1 then - local distance = playerCoords and #(playerCoords - endCoords) + -- if result ~= 1 then + -- local distance = playerCoords and #(playerCoords - endCoords) - if flag == 30 and entityHit then - entityHit = HasEntityClearLosToEntity(entityHit, playerPed, 7) and entityHit - end + -- if flag == 30 and entityHit then + -- entityHit = HasEntityClearLosToEntity(entityHit, playerPed, 7) and entityHit + -- end - local entityType = entityHit and GetEntityType(entityHit) + -- local entityType = entityHit and GetEntityType(entityHit) - if entityType == 0 and pcall(GetEntityModel, entityHit) then - entityType = 3 - end + -- if entityType == 0 and pcall(GetEntityModel, entityHit) then + -- entityType = 3 + -- end - return endCoords, distance, entityHit, entityType or 0 - end + -- return endCoords, distance, entityHit, entityType or 0 + -- end - Wait(0) - end + -- Wait(0) + -- end +-- end +local function RaycastCamera(flag, playerCoords) + -- Caching für Performance und Sicherheit + local DoesEntityExist = DoesEntityExist + local GetEntityType = GetEntityType + + if not playerPed then playerPed = PlayerPedId() end + if not playerCoords then playerCoords = GetEntityCoords(playerPed) end + + local rayPos, rayDir = ScreenPositionToCameraRay() + local destination = rayPos + 16 * rayDir + -- Wir nutzen hier 4 für p4 (den Flag für 'peds'), aber der 'flag' Parameter steuert die Kollision + local rayHandle = StartShapeTestLosProbe(rayPos.x, rayPos.y, rayPos.z, destination.x, destination.y, destination.z, + flag or -1, playerPed, 4) + + while true do + local result, _, endCoords, _, entityHit = GetShapeTestResult(rayHandle) + + if result ~= 1 then -- ShapeTest ist fertig + local distance = #(playerCoords - endCoords) + + -- 1. SÄULE: Existenz-Check (Verhindert den Native-Crash) + if not entityHit or entityHit == 0 or entityHit == -1 or not DoesEntityExist(entityHit) then + return endCoords, distance, 0, 0 + end + + -- 2. SÄULE: LOS Check (Nur wenn flag 30 und sichergestellt ist, dass entityHit valide ist) + if flag == 30 then + -- Wichtig: Parameter-Reihenfolge bei HasEntityClearLosToEntity beachten + if not HasEntityClearLosToEntity(playerPed, entityHit, 7) then + return endCoords, distance, 0, 0 + end + end + + -- 3. SÄULE: Typ-Bestimmung + local entityType = GetEntityType(entityHit) or 0 + + -- Fallback für Objekte, falls GetEntityType 0 liefert (häufig bei MLOs/Map-Objekten) + if entityType == 0 then + local ok = pcall(GetEntityModel, entityHit) + if ok then + entityType = 3 -- Markiere als Objekt + end + end + + return endCoords, distance, entityHit, entityType + end + + Wait(0) -- Verhindert das Einfrieren des Threads während des Raycasts + end end exports('RaycastCamera', RaycastCamera)