Skip to content

Commit 68a8db6

Browse files
committed
CCamSA, CCameraSA, CCameraRPC fixes
1 parent 46ced0f commit 68a8db6

File tree

5 files changed

+185
-109
lines changed

5 files changed

+185
-109
lines changed

Client/game_sa/CCamSA.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@ CEntity* CCamSA::GetTargetEntity() const
2828

2929
void CCamSA::SetTargetEntity(CEntity* pEntity)
3030
{
31-
m_pInterface->CamTargetEntity = pEntity->GetInterface();
31+
if (pEntity)
32+
{
33+
m_pInterface->CamTargetEntity = pEntity->GetInterface();
34+
}
35+
else
36+
{
37+
m_pInterface->CamTargetEntity = nullptr;
38+
}
3239
}
3340

3441
void CCamSA::GetDirection(float& fHorizontal, float& fVertical)

Client/game_sa/CCamSA.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,19 +165,19 @@ class CCamSA : public CCam
165165
CCamSA(CCamSAInterface* pInterface) { m_pInterface = pInterface; }
166166
CCamSAInterface* GetInterface() { return m_pInterface; }
167167

168-
CVector* GetFront() const { return &m_pInterface->Front; }
169-
CVector* GetUp() const { return &m_pInterface->Up; }
170-
CVector* GetSource() const { return &m_pInterface->Source; }
171-
unsigned int GetMode() const { return m_pInterface->Mode; }
172-
float GetFOV() const { return m_pInterface->FOV; }
173-
void SetFOV(float fFOV) { m_pInterface->FOV = fFOV; }
174-
void GetDirection(float& fHorizontal, float& fVertical);
175-
void SetDirection(float fHorizontal, float fVertical);
176-
177-
CVector* GetFixedModeSource() const { return &m_pInterface->m_cvecCamFixedModeSource; }
178-
CVector* GetFixedModeVector() const { return &m_pInterface->m_cvecCamFixedModeVector; }
179-
CVector* GetTargetHistoryPos() const { return m_pInterface->m_aTargetHistoryPos; }
180-
181-
CEntity* GetTargetEntity() const;
168+
CVector* GetFront() const override { return &m_pInterface->Front; }
169+
CVector* GetUp() const override { return &m_pInterface->Up; }
170+
CVector* GetSource() const override { return &m_pInterface->Source; }
171+
unsigned int GetMode() const override { return m_pInterface->Mode; }
172+
float GetFOV() const override { return m_pInterface->FOV; }
173+
void SetFOV(float fFOV) override { m_pInterface->FOV = fFOV; }
174+
void GetDirection(float& fHorizontal, float& fVertical) override;
175+
void SetDirection(float fHorizontal, float fVertical) override;
176+
177+
CVector* GetFixedModeSource() const override { return &m_pInterface->m_cvecCamFixedModeSource; }
178+
CVector* GetFixedModeVector() const override { return &m_pInterface->m_cvecCamFixedModeVector; }
179+
CVector* GetTargetHistoryPos() const override { return m_pInterface->m_aTargetHistoryPos; }
180+
181+
CEntity* GetTargetEntity() const override;
182182
void SetTargetEntity(CEntity* pEntity) override;
183183
};

Client/game_sa/CCameraSA.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,17 @@ void CCameraSA::RestoreWithJumpCut()
7777
*/
7878
void CCameraSA::TakeControl(CEntity* entity, eCamMode CamMode, int CamSwitchStyle)
7979
{
80+
if (!entity)
81+
return;
82+
8083
CEntitySA* pEntitySA = dynamic_cast<CEntitySA*>(entity);
8184
if (!pEntitySA)
8285
return;
8386

8487
CEntitySAInterface* entityInterface = pEntitySA->GetInterface();
88+
if (!entityInterface)
89+
return;
90+
8591
CCameraSAInterface* cameraInterface = GetInterface();
8692
// __thiscall
8793

@@ -99,6 +105,9 @@ void CCameraSA::TakeControl(CEntity* entity, eCamMode CamMode, int CamSwitchStyl
99105

100106
void CCameraSA::TakeControl(CVector* position, int CamSwitchStyle)
101107
{
108+
if (!position)
109+
return;
110+
102111
CCameraSAInterface* cameraInterface = GetInterface();
103112
// __thiscall
104113
CVector vecOffset;
@@ -210,7 +219,10 @@ CMatrix* CCameraSA::GetMatrix(CMatrix* matrix)
210219

211220
void CCameraSA::SetMatrix(CMatrix* matrix)
212221
{
213-
CMatrix_Padded* pCamMatrix = GetInterface()->matrix;
222+
if (!matrix)
223+
return;
224+
225+
CMatrix_Padded* pCamMatrix = &GetInterface()->m_cameraMatrix;
214226
if (pCamMatrix)
215227
{
216228
pCamMatrix->vFront = matrix->vFront;
@@ -446,7 +458,7 @@ float CCameraSA::GetShakeForce()
446458

447459
void CCameraSA::ShakeCamera(float radius, float x, float y, float z) noexcept
448460
{
449-
static CCameraSAInterface* cameraInterface = GetInterface();
461+
CCameraSAInterface* cameraInterface = GetInterface();
450462
if (radius <= 0.0f)
451463
return ResetShakeCamera();
452464

Client/game_sa/CCameraSA.h

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -382,40 +382,42 @@ class CCameraSA : public CCamera
382382
~CCameraSA();
383383

384384
CCameraSAInterface* GetInterface() { return internalInterface; };
385-
void TakeControl(CEntity* entity, eCamMode CamMode, int CamSwitchStyle);
386-
void TakeControl(CVector* position, int CamSwitchStyle);
387-
void Restore();
388-
void RestoreWithJumpCut();
389-
CMatrix* GetMatrix(CMatrix* matrix);
390-
void SetMatrix(CMatrix* matrix);
391-
void Find3rdPersonCamTargetVector(float fDistance, CVector* vecGunMuzzle, CVector* vecSource, CVector* vecTarget);
392-
float Find3rdPersonQuickAimPitch();
393-
BYTE GetActiveCam();
394-
395-
CCam* GetCam(BYTE bCameraID);
385+
386+
// CCamera interface implementation
387+
void TakeControl(CEntity* entity, eCamMode CamMode, int CamSwitchStyle) override;
388+
void TakeControl(CVector* position, int CamSwitchStyle) override;
389+
void Restore() override;
390+
void RestoreWithJumpCut() override;
391+
CMatrix* GetMatrix(CMatrix* matrix) override;
392+
void SetMatrix(CMatrix* matrix) override;
393+
void Find3rdPersonCamTargetVector(float fDistance, CVector* vecGunMuzzle, CVector* vecSource, CVector* vecTarget) override;
394+
float Find3rdPersonQuickAimPitch() override;
395+
BYTE GetActiveCam() override;
396+
CCam* GetCam(BYTE bCameraID) override;
397+
void SetWidescreen(bool bWidescreen) override;
398+
bool GetWidescreen() override;
399+
bool IsFading() override;
400+
int GetFadingDirection() override;
401+
void Fade(float fFadeOutTime, int iOutOrIn) override;
402+
void SetFadeColor(unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue) override;
403+
float GetCameraRotation() override;
404+
RwMatrix* GetLTM() override;
405+
CEntity* GetTargetEntity() override;
406+
void SetCameraClip(bool bObjects, bool bVehicles) override;
407+
void GetCameraClip(bool& bObjects, bool& bVehicles) override;
408+
BYTE GetCameraVehicleViewMode() override;
409+
BYTE GetCameraPedViewMode() override;
410+
void SetCameraVehicleViewMode(BYTE dwCamMode) override;
411+
void SetCameraPedViewMode(BYTE dwCamMode) override;
412+
void SetShakeForce(float fShakeForce) override;
413+
float GetShakeForce() override;
414+
void ShakeCamera(float radius, float x, float y, float z) noexcept override;
415+
void ResetShakeCamera() noexcept override;
416+
std::uint8_t GetTransitionState() override;
417+
418+
// Additional overload not in base interface
396419
virtual CCam* GetCam(CCamSAInterface* camInterface);
397-
398-
void SetWidescreen(bool bWidescreen);
399-
bool GetWidescreen();
400-
bool IsFading();
401-
int GetFadingDirection();
402-
void Fade(float fFadeOutTime, int iOutOrIn);
403-
void SetFadeColor(unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue);
404-
float GetCameraRotation();
405-
RwMatrix* GetLTM();
406-
CEntity* GetTargetEntity();
407-
void SetCameraClip(bool bObjects, bool bVehicles);
408-
void GetCameraClip(bool& bObjects, bool& bVehicles);
409-
BYTE GetCameraVehicleViewMode();
410-
BYTE GetCameraPedViewMode();
411-
void SetCameraVehicleViewMode(BYTE dwCamMode);
412-
void SetCameraPedViewMode(BYTE dwCamMode);
420+
421+
// Additional methods
413422
void RestoreLastGoodState();
414-
void SetShakeForce(float fShakeForce);
415-
float GetShakeForce();
416-
417-
void ShakeCamera(float radius, float x, float y, float z) noexcept override;
418-
void ResetShakeCamera() noexcept override;
419-
420-
std::uint8_t GetTransitionState();
421423
};

Client/mods/deathmatch/logic/rpc/CCameraRPCs.cpp

Lines changed: 113 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -22,82 +22,122 @@ void CCameraRPCs::LoadFunctions()
2222

2323
void CCameraRPCs::SetCameraMatrix(NetBitStreamInterface& bitStream)
2424
{
25+
if (!m_pCamera)
26+
return;
27+
2528
if (bitStream.Version() >= 0x5E)
2629
{
2730
uchar ucTimeContext;
28-
if (bitStream.Read(ucTimeContext))
29-
m_pCamera->SetSyncTimeContext(ucTimeContext);
31+
if (!bitStream.Read(ucTimeContext))
32+
{
33+
return;
34+
}
35+
m_pCamera->SetSyncTimeContext(ucTimeContext);
3036
}
3137

3238
CVector vecPosition, vecLookAt;
3339
float fRoll = 0.0f;
3440
float fFOV = 70.0f;
35-
if (bitStream.Read(vecPosition.fX) && bitStream.Read(vecPosition.fY) && bitStream.Read(vecPosition.fZ) && bitStream.Read(vecLookAt.fX) &&
36-
bitStream.Read(vecLookAt.fY) && bitStream.Read(vecLookAt.fZ))
41+
42+
if (!bitStream.Read(vecPosition.fX) || !bitStream.Read(vecPosition.fY) || !bitStream.Read(vecPosition.fZ) ||
43+
!bitStream.Read(vecLookAt.fX) || !bitStream.Read(vecLookAt.fY) || !bitStream.Read(vecLookAt.fZ))
3744
{
38-
bitStream.Read(fRoll);
39-
bitStream.Read(fFOV);
45+
return; // Invalid data
46+
}
4047

41-
if (!m_pCamera->IsInFixedMode())
42-
m_pCamera->ToggleCameraFixedMode(true);
48+
bitStream.Read(fRoll);
49+
bitStream.Read(fFOV);
4350

44-
// Put the camera there
45-
m_pCamera->SetPosition(vecPosition);
46-
m_pCamera->SetFixedTarget(vecLookAt, fRoll);
47-
m_pCamera->SetFOV(fFOV);
51+
// Validate float values to prevent potential issues
52+
if (!std::isfinite(fRoll) || !std::isfinite(fFOV) ||
53+
!std::isfinite(vecPosition.fX) || !std::isfinite(vecPosition.fY) || !std::isfinite(vecPosition.fZ) ||
54+
!std::isfinite(vecLookAt.fX) || !std::isfinite(vecLookAt.fY) || !std::isfinite(vecLookAt.fZ))
55+
{
56+
return; // Invalid float values (NaN, infinity, etc.)
4857
}
58+
59+
// Validate camera pointer before use
60+
if (!m_pCamera)
61+
return;
62+
63+
if (!m_pCamera->IsInFixedMode())
64+
m_pCamera->ToggleCameraFixedMode(true);
65+
66+
// Put the camera there
67+
m_pCamera->SetPosition(vecPosition);
68+
m_pCamera->SetFixedTarget(vecLookAt, fRoll);
69+
m_pCamera->SetFOV(fFOV);
4970
}
5071

5172
void CCameraRPCs::SetCameraTarget(NetBitStreamInterface& bitStream)
5273
{
74+
if (!m_pCamera)
75+
return;
76+
5377
if (bitStream.Version() >= 0x5E)
5478
{
5579
uchar ucTimeContext;
56-
if (bitStream.Read(ucTimeContext))
57-
m_pCamera->SetSyncTimeContext(ucTimeContext);
80+
if (!bitStream.Read(ucTimeContext))
81+
{
82+
return;
83+
}
84+
m_pCamera->SetSyncTimeContext(ucTimeContext);
5885
}
5986

6087
ElementID targetID;
61-
if (bitStream.Read(targetID))
88+
if (!bitStream.Read(targetID))
89+
return;
90+
91+
// Validate camera pointer
92+
if (!m_pCamera)
93+
return;
94+
95+
CClientEntity* pEntity = CElementIDs::GetElement(targetID);
96+
if (!pEntity)
97+
return;
98+
99+
// Check if entity is being deleted - critical memory safety check
100+
if (pEntity->IsBeingDeleted())
101+
return;
102+
103+
switch (pEntity->GetType())
62104
{
63-
CClientEntity* pEntity = CElementIDs::GetElement(targetID);
64-
if (pEntity)
105+
case CCLIENTPLAYER:
65106
{
66-
switch (pEntity->GetType())
107+
CClientPlayer* pPlayer = static_cast<CClientPlayer*>(pEntity);
108+
if (pPlayer->IsLocalPlayer())
67109
{
68-
case CCLIENTPLAYER:
69-
{
70-
CClientPlayer* pPlayer = static_cast<CClientPlayer*>(pEntity);
71-
if (pPlayer->IsLocalPlayer())
72-
{
73-
// Return the focus to the local player
74-
m_pCamera->SetFocusToLocalPlayer();
75-
}
76-
else
77-
{
78-
// Put the focus on that player
79-
m_pCamera->SetFocus(pPlayer, MODE_CAM_ON_A_STRING, false);
80-
}
81-
break;
82-
}
83-
case CCLIENTPED:
84-
case CCLIENTVEHICLE:
85-
{
86-
m_pCamera->SetFocus(pEntity, MODE_CAM_ON_A_STRING, false);
87-
break;
88-
}
89-
default:
90-
return;
110+
// Return the focus to the local player
111+
m_pCamera->SetFocusToLocalPlayer();
91112
}
113+
else
114+
{
115+
// Put the focus on that player
116+
m_pCamera->SetFocus(pPlayer, MODE_CAM_ON_A_STRING, false);
117+
}
118+
break;
119+
}
120+
case CCLIENTPED:
121+
case CCLIENTVEHICLE:
122+
{
123+
m_pCamera->SetFocus(pEntity, MODE_CAM_ON_A_STRING, false);
124+
break;
92125
}
126+
default:
127+
// Invalid entity type for camera target
128+
return;
93129
}
94130
}
95131

96132
void CCameraRPCs::SetCameraInterior(NetBitStreamInterface& bitStream)
97133
{
98-
// Read out the camera mode
134+
// Read out the camera interior
99135
unsigned char ucInterior;
100-
if (bitStream.Read(ucInterior))
136+
if (!bitStream.Read(ucInterior))
137+
return;
138+
139+
// Validate game pointer before use
140+
if (g_pGame && g_pGame->GetWorld())
101141
{
102142
g_pGame->GetWorld()->SetCurrentArea(ucInterior);
103143
}
@@ -107,26 +147,41 @@ void CCameraRPCs::FadeCamera(NetBitStreamInterface& bitStream)
107147
{
108148
unsigned char ucFadeIn;
109149
float fFadeTime = 1.0f;
110-
if (bitStream.Read(ucFadeIn) && bitStream.Read(fFadeTime))
111-
{
112-
g_pClientGame->SetInitiallyFadedOut(false);
150+
151+
if (!bitStream.Read(ucFadeIn) || !bitStream.Read(fFadeTime))
152+
return;
153+
154+
// Validate pointers before use
155+
if (!m_pCamera || !g_pClientGame)
156+
return;
113157

114-
if (ucFadeIn)
158+
g_pClientGame->SetInitiallyFadedOut(false);
159+
160+
if (ucFadeIn)
161+
{
162+
m_pCamera->FadeIn(fFadeTime);
163+
164+
// Validate game and HUD pointers
165+
if (g_pGame && g_pGame->GetHud())
115166
{
116-
m_pCamera->FadeIn(fFadeTime);
117167
g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, !g_pClientGame->GetHudAreaNameDisabled());
118168
}
119-
else
120-
{
121-
unsigned char ucRed = 0;
122-
unsigned char ucGreen = 0;
123-
unsigned char ucBlue = 0;
169+
}
170+
else
171+
{
172+
unsigned char ucRed = 0;
173+
unsigned char ucGreen = 0;
174+
unsigned char ucBlue = 0;
124175

125-
if (bitStream.Read(ucRed) && bitStream.Read(ucGreen) && bitStream.Read(ucBlue))
126-
{
127-
m_pCamera->FadeOut(fFadeTime, ucRed, ucGreen, ucBlue);
128-
g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false);
129-
}
176+
if (!bitStream.Read(ucRed) || !bitStream.Read(ucGreen) || !bitStream.Read(ucBlue))
177+
return;
178+
179+
m_pCamera->FadeOut(fFadeTime, ucRed, ucGreen, ucBlue);
180+
181+
// Validate game and HUD pointers
182+
if (g_pGame && g_pGame->GetHud())
183+
{
184+
g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false);
130185
}
131186
}
132187
}

0 commit comments

Comments
 (0)