1212#include " StdInc.h"
1313#include " CCameraSA.h"
1414#include " CGameSA.h"
15+ #include < mutex>
16+ #include < cmath>
1517
1618extern CGameSA* pGame;
1719
20+ static std::mutex s_cameraClipMutex;
1821static bool bCameraClipObjects;
1922static bool bCameraClipVehicles;
2023
@@ -28,19 +31,54 @@ void HOOK_Camera_CollisionDetection();
2831
2932CCameraSA::CCameraSA (CCameraSAInterface* cameraInterface)
3033{
34+ if (!cameraInterface)
35+ {
36+ internalInterface = nullptr ;
37+ // Initialize all camera pointers to null
38+ for (int i = 0 ; i < MAX_CAMS; i++)
39+ Cams[i] = nullptr ;
40+ return ;
41+ }
42+
3143 internalInterface = cameraInterface;
44+
3245 for (int i = 0 ; i < MAX_CAMS; i++)
33- Cams[i] = new CCamSA (&internalInterface->Cams [i]);
34- bCameraClipObjects = true ;
35- bCameraClipVehicles = true ;
46+ {
47+ try {
48+ Cams[i] = new CCamSA (&internalInterface->Cams [i]);
49+ }
50+ catch (...)
51+ {
52+ // Clean up on failure
53+ for (int j = 0 ; j < i; j++)
54+ {
55+ delete Cams[j];
56+ Cams[j] = nullptr ;
57+ }
58+ internalInterface = nullptr ;
59+ throw ;
60+ }
61+ }
62+
63+ // Thread-safe initialization
64+ {
65+ std::lock_guard<std::mutex> lock (s_cameraClipMutex);
66+ bCameraClipObjects = true ;
67+ bCameraClipVehicles = true ;
68+ }
69+
3670 HookInstall (HOOKPOS_Camera_CollisionDetection, (DWORD)HOOK_Camera_CollisionDetection, 5 );
3771}
3872
3973CCameraSA::~CCameraSA ()
4074{
4175 for (int i = 0 ; i < MAX_CAMS; i++)
4276 {
43- delete Cams[i];
77+ if (Cams[i])
78+ {
79+ delete Cams[i];
80+ Cams[i] = nullptr ;
81+ }
4482 }
4583}
4684
@@ -89,7 +127,11 @@ void CCameraSA::TakeControl(CEntity* entity, eCamMode CamMode, int CamSwitchStyl
89127 return ;
90128
91129 CCameraSAInterface* cameraInterface = GetInterface ();
92- // __thiscall
130+ if (!cameraInterface)
131+ return ;
132+
133+ if (CamSwitchStyle < 0 || CamSwitchStyle > 10 )
134+ return ;
93135
94136 DWORD CCamera__TakeControl = FUNC_TakeControl;
95137 _asm
@@ -196,7 +238,17 @@ void CCameraSA::RestoreLastGoodState()
196238
197239CMatrix* CCameraSA::GetMatrix (CMatrix* matrix)
198240{
199- CMatrix_Padded* pCamMatrix = &GetInterface ()->m_cameraMatrix ; // ->matrix;
241+ if (!matrix)
242+ return nullptr ;
243+
244+ CCameraSAInterface* cameraInterface = GetInterface ();
245+ if (!cameraInterface)
246+ {
247+ *matrix = CMatrix ();
248+ return matrix;
249+ }
250+
251+ CMatrix_Padded* pCamMatrix = &cameraInterface->m_cameraMatrix ;
200252 if (pCamMatrix)
201253 {
202254 matrix->vFront = pCamMatrix->vFront ;
@@ -234,11 +286,26 @@ void CCameraSA::SetMatrix(CMatrix* matrix)
234286
235287void CCameraSA::Find3rdPersonCamTargetVector (float fDistance , CVector* vecGunMuzzle, CVector* vecSource, CVector* vecTarget)
236288{
289+ if (!vecGunMuzzle || !vecSource || !vecTarget)
290+ return ;
291+
292+ // Validate float parameter to prevent NaN/infinity issues
293+ if (!std::isfinite (fDistance ) || fDistance < 0 .0f )
294+ return ;
295+
237296 float fOriginX = vecGunMuzzle->fX ;
238297 float fOriginY = vecGunMuzzle->fY ;
239298 float fOriginZ = vecGunMuzzle->fZ ;
299+
300+ if (!std::isfinite (fOriginX ) || !std::isfinite (fOriginY ) || !std::isfinite (fOriginZ ))
301+ return ;
302+
240303 DWORD dwFunc = FUNC_Find3rdPersonCamTargetVector;
241304 CCameraSAInterface* cameraInterface = GetInterface ();
305+
306+ if (!cameraInterface)
307+ return ;
308+
242309 _asm
243310 {
244311 mov ecx, cameraInterface
@@ -334,8 +401,18 @@ int CCameraSA::GetFadingDirection()
334401
335402void CCameraSA::Fade (float fFadeOutTime , int iOutOrIn)
336403{
404+ if (!std::isfinite (fFadeOutTime ) || fFadeOutTime < 0 .0f || fFadeOutTime > 60 .0f )
405+ return ;
406+
407+ if (iOutOrIn < 0 || iOutOrIn > 1 )
408+ return ;
409+
337410 DWORD dwFunc = FUNC_Fade;
338411 CCameraSAInterface* cameraInterface = GetInterface ();
412+
413+ if (!cameraInterface)
414+ return ;
415+
339416 _asm
340417 {
341418 mov ecx, cameraInterface
@@ -369,8 +446,18 @@ float CCameraSA::GetCameraRotation()
369446
370447RwMatrix* CCameraSA::GetLTM ()
371448{
449+ CCameraSAInterface* cameraInterface = GetInterface ();
450+ if (!cameraInterface)
451+ return nullptr ;
452+
453+ if (!cameraInterface->m_pRwCamera )
454+ return nullptr ;
455+
456+ if (!cameraInterface->m_pRwCamera ->object .object .parent )
457+ return nullptr ;
458+
372459 // RwFrameGetLTM
373- return ((RwMatrix*(_cdecl*)(void *))0x7F0990 )(GetInterface () ->m_pRwCamera ->object .object .parent );
460+ return ((RwMatrix*(_cdecl*)(void *))0x7F0990 )(cameraInterface ->m_pRwCamera ->object .object .parent );
374461}
375462
376463CEntity* CCameraSA::GetTargetEntity ()
@@ -386,12 +473,16 @@ CEntity* CCameraSA::GetTargetEntity()
386473
387474void CCameraSA::SetCameraClip (bool bObjects, bool bVehicles)
388475{
476+ // Thread-safe access to static variables
477+ std::lock_guard<std::mutex> lock (s_cameraClipMutex);
389478 bCameraClipObjects = bObjects;
390479 bCameraClipVehicles = bVehicles;
391480}
392481
393482void CCameraSA::GetCameraClip (bool & bObjects, bool & bVehicles)
394483{
484+ // Thread-safe access to static variables
485+ std::lock_guard<std::mutex> lock (s_cameraClipMutex);
395486 bObjects = bCameraClipObjects;
396487 bVehicles = bCameraClipVehicles;
397488}
0 commit comments