Skip to content

Commit

Permalink
Disable Animation Hooks for Smotra server
Browse files Browse the repository at this point in the history
Three changes were made in this commit:

1. There is an animation crash that occurs at offset 0xcfcd6 in CAnimBlendNode::GetCurrentTranslation (One of the top 5 crash in MTA). We do not know the cause of the crash so we need to find out whether it's related to IFP animation hooks or not. Smotra server ranks no.1 in crash reports at this offset, so I disabled IFP hooks for smotra servers. In 10 days, we will know whether the crash is related to IFP hooks or not, we can then remove the check for smotra server to enable IFP hooks there.

2. CopyAnimation hook has been removed as it was unnecessary, still there is one hook in CMultiplayerSA_FixBadAnimId.cpp that must execute for smotra server which averts an old crash, but it can be removed completely after 10 days when we are done with testing.

3. I realized that OnCAnimBlendAssocGroupCopyAnimation_FixBadAnim function was not called if m_pAddAnimationHandler or m_pAddAnimationAndSyncHandler is nullptr, this can possibly cause a crash if animation is corrupt, rare but it can happen. This problem has been fixed now.
  • Loading branch information
fcs49 committed Nov 1, 2018
1 parent 42dd5b3 commit 5b1da08
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 187 deletions.
27 changes: 24 additions & 3 deletions Client/core/CCore.cpp
Expand Up @@ -1367,8 +1367,6 @@ void CCore::RegisterCommands()
m_pCommands->Add("showframegraph", _("shows the frame timing graph"), CCommandFuncs::ShowFrameGraph);
m_pCommands->Add("jinglebells", "", CCommandFuncs::JingleBells);
m_pCommands->Add("fakelag", "", CCommandFuncs::FakeLag);

m_pCommands->Add("reloadnews", "for developers: reload news", CCommandFuncs::ReloadNews);
}

void CCore::SwitchRenderWindow(HWND hWnd, HWND hWndInput)
Expand Down Expand Up @@ -1828,7 +1826,7 @@ void CCore::ApplyQueuedFrameRateLimit()
// Calc required time in ms between frames
const double dTargetTimeToUse = 1000.0 / m_uiQueuedFrameRate;

while(true)
while (true)
{
// See if we need to wait
double dSpare = dTargetTimeToUse - m_FrameRateTimer.Get();
Expand Down Expand Up @@ -2273,3 +2271,26 @@ SString CCore::GetBlueCopyrightString(void)
SString strCopyright = BLUE_COPYRIGHT_STRING;
return strCopyright.Replace("%BUILD_YEAR%", std::to_string(BUILD_YEAR).c_str());
}

bool CCore::IsHostSmotraServer()
{
unsigned int uiPort;
SString strHost;
CVARS_GET("host", strHost);
CVARS_GET("port", uiPort);

if (uiPort != 22003)
{
return false;
}

unsigned int arrSmotraHostIps[3] = {HashString("164.132.204.62"), HashString("149.202.223.26"), HashString("151.80.111.167")};
for (int i = 0; i < 3; i++)
{
if (arrSmotraHostIps[i] == HashString(strHost))
{
return true;
}
}
return false;
}
2 changes: 2 additions & 0 deletions Client/core/CCore.h
Expand Up @@ -276,6 +276,8 @@ class CCore : public CCoreInterface, public CSingleton<CCore>
bool IsFakeLagCommandEnabled(void) { return m_bFakeLagCommandEnabled; }
SString GetBlueCopyrightString(void);

bool IsHostSmotraServer();

private:
// Core devices.
CXML* m_pXML;
Expand Down
15 changes: 9 additions & 6 deletions Client/mods/deathmatch/logic/CClientGame.cpp
Expand Up @@ -237,6 +237,9 @@ CClientGame::CClientGame(bool bLocalPlay)
// Singular file download manager
m_pSingularFileDownloadManager = new CSingularFileDownloadManager();

bool bIsHostSmotraServer = g_pCore->IsHostSmotraServer();
g_pMultiplayer->InitializeAnimationHooks(bIsHostSmotraServer);

// Register the message and the net packet handler
g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire);
g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire);
Expand Down Expand Up @@ -4534,7 +4537,7 @@ bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface*& pCollidingVehicl
CVehicle* pColliderVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidingVehicle);
CClientEntity* pVehicleClientEntity = m_pManager->FindEntity(pColliderVehicle, true);
auto pClientVehicle = static_cast<CClientVehicle*>(pVehicleClientEntity);

if (pVehicleClientEntity)
{
CEntity* pCollidedWithEntity = g_pGame->GetPools()->GetEntity((DWORD*)pCollidedWith);
Expand Down Expand Up @@ -6904,25 +6907,25 @@ void CClientGame::RemoveAnimationAssociationFromMap(CAnimBlendAssociationSAInter
}

void CClientGame::PedStepHandler(CPedSAInterface* pPedSA, bool bFoot)
{
{
CLuaArguments Arguments;
CClientPed* pClientPed = DynamicCast<CClientPed>(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedSA));
CClientPed* pClientPed = DynamicCast<CClientPed>(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedSA));
Arguments.PushBoolean(bFoot);
pClientPed->CallEvent("onClientPedStep", Arguments, true);
}

void CClientGame::WaterCannonHitWorldHandler(SWaterCannonHitEvent& event)
{
CClientEntity* const pVehicle = event.pGameVehicle ? g_pClientGame->GetGameEntityXRefManager()->FindClientVehicle(event.pGameVehicle) : nullptr;

if (!pVehicle)
return;

CClientEntity* pEntity = event.pHitGameEntity ? g_pClientGame->GetGameEntityXRefManager()->FindClientEntity(event.pHitGameEntity) : nullptr;

if (!pEntity)
pEntity = m_pRootEntity;

CLuaArguments arguments;
arguments.PushElement(pVehicle);
arguments.PushNumber(event.vecPosition.fX);
Expand Down
49 changes: 32 additions & 17 deletions Client/multiplayer_sa/CMultiplayerSA.cpp
Expand Up @@ -155,7 +155,7 @@ DWORD RETURN_CEventHandler_ComputeKnockOffBikeResponse = 0x4BA076;
#define HOOKPOS_CAnimBlendAssociation_SetCurrentTime 0x4CEA80
#define HOOKPOS_RpAnimBlendClumpUpdateAnimations 0x4D34F0
#define HOOKPOS_CAnimBlendAssoc_destructor 0x4CECF0
#define HOOKPOS_CAnimBlendAssocGroup_CopyAnimation 0x4CE14C
#define HOOKPOS_CAnimBlendAssocGroupCopyAnimation 0x4CE130
#define HOOKPOS_CAnimManager_AddAnimation 0x4d3aa0
#define HOOKPOS_CAnimManager_AddAnimationAndSync 0x4D3B30
#define HOOKPOS_CAnimManager_BlendAnimation_Hierarchy 0x4D453E
Expand Down Expand Up @@ -422,7 +422,7 @@ void HOOK_RpAnimBlendClumpUpdateAnimations();
void HOOK_CAnimBlendAssoc_destructor();
void HOOK_CAnimManager_AddAnimation();
void HOOK_CAnimManager_AddAnimationAndSync();
void HOOK_CAnimBlendAssocGroup_CopyAnimation();
void HOOK_CAnimBlendAssocGroupCopyAnimation();
void HOOK_CAnimManager_BlendAnimation_Hierarchy();
void HOOK_CPed_GetWeaponSkill();
void HOOK_CPed_AddGogglesModel();
Expand Down Expand Up @@ -640,10 +640,6 @@ void CMultiplayerSA::InitHooks()
HookInstall(HOOKPOS_CAnimBlendAssociation_SetCurrentTime, (DWORD)HOOK_CAnimBlendAssociation_SetCurrentTime, 8);
HookInstall(HOOKPOS_RpAnimBlendClumpUpdateAnimations, (DWORD)HOOK_RpAnimBlendClumpUpdateAnimations, 8);
HookInstall(HOOKPOS_CAnimBlendAssoc_destructor, (DWORD)HOOK_CAnimBlendAssoc_destructor, 6);
HookInstall(HOOKPOS_CAnimManager_AddAnimation, (DWORD)HOOK_CAnimManager_AddAnimation, 10);
HookInstall(HOOKPOS_CAnimManager_AddAnimationAndSync, (DWORD)HOOK_CAnimManager_AddAnimationAndSync, 10);
HookInstall(HOOKPOS_CAnimBlendAssocGroup_CopyAnimation, (DWORD)HOOK_CAnimBlendAssocGroup_CopyAnimation, 5);
HookInstall(HOOKPOS_CAnimManager_BlendAnimation_Hierarchy, (DWORD)HOOK_CAnimManager_BlendAnimation_Hierarchy, 5);
HookInstall(HOOKPOS_CPed_GetWeaponSkill, (DWORD)HOOK_CPed_GetWeaponSkill, 8);
HookInstall(HOOKPOS_CPed_AddGogglesModel, (DWORD)HOOK_CPed_AddGogglesModel, 6);
HookInstall(HOOKPOS_CPhysical_ProcessCollisionSectorList, (DWORD)HOOK_CPhysical_ProcessCollisionSectorList, 7);
Expand Down Expand Up @@ -1494,9 +1490,9 @@ void CMultiplayerSA::InitHooks()
MemSetFast((void*)0x60D861, 0x90, 14);

// Allow water cannon to hit objects and players visually
MemSet((void*)0x72925D, 0x1, 1); // objects
MemSet((void*)0x729263, 0x1, 1); // players
MemSet((void*)0x72925D, 0x1, 1); // objects
MemSet((void*)0x729263, 0x1, 1); // players

InitHooks_CrashFixHacks();

// Init our 1.3 hooks.
Expand Down Expand Up @@ -1536,6 +1532,30 @@ void RemoveFxSystemPointer(DWORD* pPointer)
}
}

void CMultiplayerSA::InitializeAnimationHooks(bool bIsHostSmotra)
{
if (bIsHostSmotra)
{
BYTE originalCode_CAnimManager_AddAnimation[10] = {0x8B, 0x44, 0x24, 0x0C, 0x8B, 0x15, 0x34, 0xEA, 0xB4, 0x0};
BYTE originalCode_CAnimManager_AddAnimationAndSync[10] = {0x8B, 0x44, 0x24, 0x10, 0x8B, 0x15, 0x34, 0xEA, 0xB4, 0x00};
BYTE originalCode_CAnimManager_BlendAnimation_Hierarchy[5] = {0x8B, 0x54, 0x24, 0x2C, 0x51};
MemCpy((LPVOID)HOOKPOS_CAnimManager_AddAnimation, &originalCode_CAnimManager_AddAnimation, 10);
MemCpy((LPVOID)HOOKPOS_CAnimManager_AddAnimationAndSync, &originalCode_CAnimManager_AddAnimationAndSync, 10);
MemCpy((LPVOID)HOOKPOS_CAnimManager_BlendAnimation_Hierarchy, &originalCode_CAnimManager_BlendAnimation_Hierarchy, 5);

HookInstall(HOOKPOS_CAnimBlendAssocGroupCopyAnimation, (DWORD)HOOK_CAnimBlendAssocGroupCopyAnimation, 6);
}
else
{
BYTE originalCode_CAnimBlendAssocGroupCopyAnimation[6] = {0x64, 0xA1, 0x00, 0x00, 0x00, 0x00};
MemCpy((LPVOID)HOOKPOS_CAnimBlendAssocGroupCopyAnimation, &originalCode_CAnimBlendAssocGroupCopyAnimation, 6);

HookInstall(HOOKPOS_CAnimManager_AddAnimation, (DWORD)HOOK_CAnimManager_AddAnimation, 10);
HookInstall(HOOKPOS_CAnimManager_AddAnimationAndSync, (DWORD)HOOK_CAnimManager_AddAnimationAndSync, 10);
HookInstall(HOOKPOS_CAnimManager_BlendAnimation_Hierarchy, (DWORD)HOOK_CAnimManager_BlendAnimation_Hierarchy, 5);
}
}

CRemoteDataStorage* CMultiplayerSA::CreateRemoteDataStorage()
{
return new CRemoteDataStorageSA();
Expand Down Expand Up @@ -4215,7 +4235,7 @@ void _cdecl CPhysical_ApplyGravity(DWORD dwThis)
}
}

const float kfTimeStepOrg = 5.0f/3.0f;
const float kfTimeStepOrg = 5.0f / 3.0f;
void _declspec(naked) HOOK_CVehicle_ApplyBoatWaterResistance()
{
_asm
Expand Down Expand Up @@ -6801,15 +6821,10 @@ static void __cdecl WaterCannonHitWorld(CVehicleSAInterface* pGameVehicle, CColP
if (m_pWaterCannonHitWorldHandler)
{
CEntitySAInterface* const pGameEntity = ppGameEntity ? *ppGameEntity : nullptr;
const int iModel = pGameEntity ? pGameEntity->m_nModelIndex : -1;
const int iModel = pGameEntity ? pGameEntity->m_nModelIndex : -1;

SWaterCannonHitEvent event = {
pGameVehicle,
pGameEntity,
pColPoint->Position,
pColPoint->Normal,
iModel,
pColPoint->ucSurfaceTypeB,
pGameVehicle, pGameEntity, pColPoint->Position, pColPoint->Normal, iModel, pColPoint->ucSurfaceTypeB,
};

m_pWaterCannonHitWorldHandler(event);
Expand Down
2 changes: 2 additions & 0 deletions Client/multiplayer_sa/CMultiplayerSA.h
Expand Up @@ -80,6 +80,8 @@ class CMultiplayerSA : public CMultiplayer
void RemoveRemoteDataStorage(CPlayerPed* pPed);
void EnableHooks_ClothesMemFix(bool bEnable);

void InitializeAnimationHooks(bool bIsHostSmotra);

CPed* GetContextSwitchedPed(void);

CPopulationMP* GetPopulationMP() { return Population; }
Expand Down

4 comments on commit 5b1da08

@qaisjp
Copy link
Contributor

@qaisjp qaisjp commented on 5b1da08 Nov 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a good idea to split your work into atomic commits. That way someone who wants to remove the special functionality for Smotra only has to revert the commit, and doesn't have to pick apart your commit.

I also see other random changes that haven't been described...

@fcs49
Copy link
Contributor Author

@fcs49 fcs49 commented on 5b1da08 Nov 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a good idea to split your work into atomic commits. That way someone who wants to remove the special functionality for Smotra only has to revert the commit, and doesn't have to pick apart your commit.

It was not planned. I was only going to disable hooks for smotra but then I discovered other issues, and it was not possible to split them since they share the same hook.

I also see other random changes that haven't been described

Which ones exactly? Can you please highlight them?

@qaisjp
Copy link
Contributor

@qaisjp qaisjp commented on 5b1da08 Nov 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exes (removed in 9114c02) and reloadnews (useful for development of news items)

@fcs49
Copy link
Contributor Author

@fcs49 fcs49 commented on 5b1da08 Nov 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exes (removed in 9114c02)

^^

and reloadnews (useful for development of news items)

I have no idea why that happened. I'll restore it.

Please sign in to comment.