Browse Source

Remove Zone Heading Timers to resolve loose Spawn pointers causing crashes

Fix #387 - ASan crash on pet
Image 2 years ago
parent
commit
257a595ce0

+ 1 - 0
EQ2/source/WorldServer/NPC.cpp

@@ -255,6 +255,7 @@ bool NPC::PauseMovement(int32 period_of_time_ms)
 		StartRunback();
 	
 	RunToLocation(GetX(),GetY(),GetZ());
+	
 	pause_timer.Start(period_of_time_ms, true);
 
 	return true;

+ 2 - 0
EQ2/source/WorldServer/NPC_AI.cpp

@@ -153,6 +153,8 @@ void Brain::Think() {
 						case 6: // artificially 1500ms per 250ms Think() call
 							if (m_body->GetRunbackLocation()->gridid > 0)
 								m_body->SetLocation(m_body->GetRunbackLocation()->gridid);
+								if(m_body->GetTempActionState() == 0)
+									m_body->SetTempActionState(-1);
 							m_body->SetHeading(m_body->m_runbackHeadingDir1,m_body->m_runbackHeadingDir2,false);
 							m_body->ClearRunback();
 							m_body->SetHP(m_body->GetTotalHP());

+ 5 - 2
EQ2/source/WorldServer/Spawn.cpp

@@ -3367,9 +3367,12 @@ void Spawn::FaceTarget(float x, float z){
 void Spawn::FaceTarget(Spawn* target, bool disable_action_state){
 	if(!target)
 		return;
-	FaceTarget(target->GetX(), target->GetZ());
 	if(GetHP() > 0 && target->IsPlayer() && !EngagedInCombat()){
-		GetZone()->AddHeadingTimer(this);
+		if(IsNPC()) {
+			((NPC*)this)->StartRunback();
+			((NPC*)this)->PauseMovement(30000);
+		}
+		FaceTarget(target->GetX(), target->GetZ());
 		if(disable_action_state)
 			SetTempActionState(0);
 	}

+ 0 - 31
EQ2/source/WorldServer/zoneserver.cpp

@@ -477,7 +477,6 @@ void ZoneServer::DeleteData(bool boot_clients){
 					client->Disconnect();
 			}
 			else{
-				RemoveHeadingTimer(spawn); // called in RemoveSpawnSupportFunctions()
 				RemoveSpawnSupportFunctions(spawn, true);
 				AddPendingDelete(spawn);
 			}
@@ -563,7 +562,6 @@ void ZoneServer::DeleteData(bool boot_clients){
 	ClearDeadSpawns();
 
 	// Clear lists
-	heading_timers.clear();
 	movement_spawns.clear();
 	respawn_timers.clear();
 	transport_spawns.clear();
@@ -1455,10 +1453,6 @@ bool ZoneServer::Process()
 		if(regenTimer.Check())
 			RegenUpdate();
 
-		// heading_timers loop
-		if(!zoneShuttingDown)
-			CheckHeadingTimers();
-
 		// respawn_timers loop
 		if(respawn_timer.Check() && !zoneShuttingDown)
 			CheckRespawns();
@@ -3598,30 +3592,6 @@ void ZoneServer::PlaySoundFile(Client* client, const char* name, float origin_x,
 	}
 }
 
-void ZoneServer::AddHeadingTimer(Spawn* spawn){
-	heading_timers.Put(spawn, Timer::GetCurrentTime2() + 30000);
-}
-
-void ZoneServer::RemoveHeadingTimer(Spawn* spawn){
-	heading_timers.erase(spawn);
-}
-
-void ZoneServer::CheckHeadingTimers(){
-	if(heading_timers.size() > 0){
-		MutexMap<Spawn*, int32>::iterator itr = heading_timers.begin();
-		Spawn* spawn = 0;
-		int32 current_time = Timer::GetCurrentTime2();
-		while(itr.Next()){
-			if(current_time >= itr->second){
-				spawn = itr->first;
-				spawn->SetHeading(spawn->GetSpawnOrigHeading());
-				spawn->SetTempActionState(-1);
-				heading_timers.erase(itr->first);
-			}
-		}
-	}
-}
-
 bool ZoneServer::HasWidgetTimer(Spawn* widget){	
 	bool ret = false;
 	if (widget) {
@@ -5926,7 +5896,6 @@ void ZoneServer::RemoveSpawnSupportFunctions(Spawn* spawn, bool lock_spell_proce
 				quick_database_id_lookup.erase(spawn->GetDatabaseID());
 		}
 
-		RemoveHeadingTimer(spawn);
 		DeleteSpawnScriptTimers(spawn);
 		RemovePlayerProximity(spawn);
 	}

+ 0 - 5
EQ2/source/WorldServer/zoneserver.h

@@ -349,8 +349,6 @@ public:
 	void	AddWidgetTimer(Spawn* widget, float time);
 	bool	HasWidgetTimer(Spawn* widget);
 	
-	void	AddHeadingTimer(Spawn* spawn);
-	
 	void	Despawn(Spawn* spawn, int32 timer);
 	
 	void	RepopSpawns(Client* client, Spawn* spawn);
@@ -730,8 +728,6 @@ private:
 	void	DeleteSpawnScriptTimers(Spawn* spawn, bool all = false);											// never used outside zone server
 	void	DeleteSpawnScriptTimers();																			// never used outside zone server
 	void	CheckSpawnScriptTimers();																			// never used outside zone server
-	void	CheckHeadingTimers();																				// never used outside zone server
-	void	RemoveHeadingTimer(Spawn* spawn);																	// never used outside zone server
 	void	PrepareSpawnID(Player* player, Spawn* spawn);														// never used outside zone server
 	void	RemoveMovementNPC(Spawn* spawn);																	// never used outside zone server
 	bool	CheckNPCAttacks(NPC* npc, Spawn* victim, Client* client = 0);										// never used outside zone server
@@ -780,7 +776,6 @@ private:
 	/* Mutex Maps */
 	MutexMap<Spawn*, Client*>						client_spawn_map;								// ok
 	MutexMap<Client*, int32>						drowning_victims;
-	MutexMap<Spawn*, int32>							heading_timers;
 	MutexMap<int32, int32>							movement_spawns;								// 1st int32 = spawn id
 	MutexMap<int32, PlayerProximity*>				player_proximities;								// 1st int32 = spawn id
 	MutexMap<int32, Player*>						players_tracking;