Browse Source

Fix GetOwner pointer from causing potential crashes

Emagi 1 year ago
parent
commit
12f7170625

+ 4 - 4
EQ2/source/WorldServer/Combat.cpp

@@ -1170,7 +1170,7 @@ void Entity::AddHate(Entity* attacker, sint32 hate) {
 		return;
 
 	// If a players pet and protect self is off
-	if (IsPet() && ((NPC*)this)->GetOwner()->IsPlayer() && ((((Player*)((NPC*)this)->GetOwner())->GetInfoStruct()->get_pet_behavior() & 2) == 0))
+	if (IsPet() && ((NPC*)this)->GetOwner() && ((NPC*)this)->GetOwner()->IsPlayer() && ((((Player*)((NPC*)this)->GetOwner())->GetInfoStruct()->get_pet_behavior() & 2) == 0))
 		return;
 
 	hate = attacker->CalculateHateAmount(this, hate);
@@ -1304,7 +1304,7 @@ void Entity::KillSpawn(Spawn* dead, int8 type, int8 damage_type, int16 kill_blow
 	/* just for sake of not knowing if we are in a read lock, write lock, or no lock
 	**  say spawnlist is locked (DismissPet arg 3 true), which means RemoveSpawn will remove the id from the spawn_list outside of the potential lock
 	*/
-	if (dead->IsPet())
+	if (dead->IsPet() && ((NPC*)dead)->GetOwner())
 		((NPC*)dead)->GetOwner()->DismissPet((NPC*)dead, true, true);
 	else if (dead->IsEntity()) {
 		// remove all pets for this entity
@@ -1414,10 +1414,10 @@ void Player::ProcessCombat() {
 	combat_target = 0;
 
 	if (Target->HasTarget()) {
-		if (Target->IsPlayer() || (Target->IsNPC() && Target->IsPet() && ((NPC*)Target)->GetOwner()->IsPlayer())){
+		if (Target->IsPlayer() || (Target->IsNPC() && Target->IsPet() && ((NPC*)Target)->GetOwner() && ((NPC*)Target)->GetOwner()->IsPlayer())){
 			Spawn* secondary_target = Target->GetTarget();
 			if (secondary_target->IsNPC() && secondary_target->appearance.attackable) {
-				if (!secondary_target->IsPet() || (secondary_target->IsPet() && ((NPC*)secondary_target)->GetOwner()->IsNPC())) {
+				if (!secondary_target->IsPet() || (secondary_target->IsPet() && ((NPC*)secondary_target)->GetOwner() && ((NPC*)secondary_target)->GetOwner()->IsNPC())) {
 					combat_target = secondary_target;
 				}
 			}

+ 1 - 1
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -5613,7 +5613,7 @@ int EQ2Emu_lua_DismissPet(lua_State* state) {
 		return 0;
 	}
 
-	if (!((NPC*)spawn)->IsDismissing())
+	if (!((NPC*)spawn)->IsDismissing() && ((NPC*)spawn)->GetOwner())
 		((NPC*)spawn)->GetOwner()->DismissPet((NPC*)spawn, false, true);
 
 	return 0;

+ 3 - 3
EQ2/source/WorldServer/NPC_AI.cpp

@@ -131,7 +131,7 @@ void Brain::Think() {
 				m_body->InCombat(false);
 
 				// Do not set a players pet to full health once they stop combat
-				if (!m_body->IsPet() || (m_body->IsPet() && !m_body->GetOwner()->IsPlayer()))
+				if (!m_body->IsPet() || (m_body->IsPet() && m_body->GetOwner() && !m_body->GetOwner()->IsPlayer()))
 					m_body->SetHP(m_body->GetTotalHP());
 			}
 
@@ -463,7 +463,7 @@ bool Brain::HasRecovered() {
 void Brain::AddToEncounter(Entity* entity) {
 
 	// If player pet then set the entity to the pets owner
-	if (entity->IsPet() && ((NPC*)entity)->GetOwner()->IsPlayer())
+	if (entity->IsPet() && ((NPC*)entity)->GetOwner() && ((NPC*)entity)->GetOwner()->IsPlayer())
 		entity = ((NPC*)entity)->GetOwner();
 
 	// If player or bot then get the group
@@ -611,7 +611,7 @@ void CombatPetBrain::Think() {
 	LogWrite(NPC_AI__DEBUG, 7, "NPC_AI", "Pet AI code called for %s", GetBody()->GetName());
 
 	// If owner is a player and player has stay set then return out
-	if (GetBody()->GetOwner()->IsPlayer() && ((Player*)GetBody()->GetOwner())->GetInfoStruct()->get_pet_movement() == 1)
+	if (GetBody()->GetOwner() && GetBody()->GetOwner()->IsPlayer() && ((Player*)GetBody()->GetOwner())->GetInfoStruct()->get_pet_movement() == 1)
 		return;
 
 	// Set target to owner

+ 6 - 6
EQ2/source/WorldServer/SpellProcess.cpp

@@ -1298,7 +1298,7 @@ void SpellProcess::ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster,
 
 				if (target->IsPet())
 				{
-					if (((NPC*)target)->GetOwner()->IsNPC())
+					if (((NPC*)target)->GetOwner() && ((NPC*)target)->GetOwner()->IsNPC())
 					{
 						zone->SendSpellFailedPacket(client, SPELL_ERROR_NOT_A_FRIEND);
 						lua_spell->caster->GetZone()->GetSpellProcess()->RemoveSpellScriptTimerBySpell(lua_spell);
@@ -2045,14 +2045,14 @@ void SpellProcess::GetSpellTargets(LuaSpell* luaspell)
 					if (data->friendly_spell) {
 						//if target is NPC (and not a bot) on friendly spell, check to see if target is friendly
 						if (target->IsNPC() && !((Entity*)target)->GetInfoStruct()->get_friendly_target_npc() && !target->IsBot()) {
-							if (!target->IsPet() || (target->IsPet() && ((NPC*)target)->GetOwner()->IsNPC())) {
+							if (!target->IsPet() || (target->IsPet() && ((NPC*)target)->GetOwner() && ((NPC*)target)->GetOwner()->IsNPC())) {
 								if (secondary_target && secondary_target->IsPlayer()) {
 									target = secondary_target;
 									luaspell->initial_target = target->GetID();
 									luaspell->initial_target_char_id = (target && target->IsPlayer()) ? ((Player*)target)->GetCharacterID() : 0;
 									AddLuaSpellTarget(luaspell, target->GetID());
 								}
-								else if (secondary_target && secondary_target->IsPet() && ((NPC*)secondary_target)->GetOwner()->IsPlayer())
+								else if (secondary_target && secondary_target->IsPet() && ((NPC*)secondary_target)->GetOwner() && ((NPC*)secondary_target)->GetOwner()->IsPlayer())
 									implied = true;
 							}
 							else if (target->IsPet() && ((Entity*)target)->GetOwner()->IsPlayer())
@@ -2064,9 +2064,9 @@ void SpellProcess::GetSpellTargets(LuaSpell* luaspell)
 						}
 					}   // if spell is not friendly
 					else {   // check if there is an implied target for this non-friendly spell
-						if (target->IsPlayer() || (target->IsPet() && ((NPC*)target)->GetOwner()->IsPlayer())) {
+						if (target->IsPlayer() || (target->IsPet() && ((NPC*)target)->GetOwner() && ((NPC*)target)->GetOwner()->IsPlayer())) {
 							if (secondary_target && secondary_target->IsNPC()) {
-								if (!secondary_target->IsPet() || (secondary_target->IsPet() && ((NPC*)secondary_target)->GetOwner()->IsNPC())) {
+								if (!secondary_target->IsPet() || (secondary_target->IsPet() && ((NPC*)secondary_target)->GetOwner() && ((NPC*)secondary_target)->GetOwner()->IsNPC())) {
 									implied = true;
 								}
 							}
@@ -2094,7 +2094,7 @@ void SpellProcess::GetSpellTargets(LuaSpell* luaspell)
 			else if (caster->IsPlayer()) {
 				if (data->friendly_spell) {
 					if (target->IsNPC() && !target->IsBot()) {
-						if (!((Entity*)target)->GetInfoStruct()->get_friendly_target_npc() && (!target->IsPet() || (target->IsPet() && ((NPC*)target)->GetOwner()->IsNPC()))) {
+						if (!((Entity*)target)->GetInfoStruct()->get_friendly_target_npc() && (!target->IsPet() || (target->IsPet() && ((NPC*)target)->GetOwner() && ((NPC*)target)->GetOwner()->IsNPC()))) {
 							target = caster;
 							luaspell->initial_target = caster->GetID();
 							luaspell->initial_target_char_id = (caster && caster->IsPlayer()) ? ((Player*)caster)->GetCharacterID() : 0;

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

@@ -4906,12 +4906,6 @@ void ZoneServer::KillSpawn(bool spawnListLocked, Spawn* dead, Spawn* killer, boo
 	if (dead->IsNPC())
 		((NPC*)dead)->Brain()->ClearHate();
 
-	// ResetPetInfo() is called in DismissPet(), might not need to be here
-
-	// Players pet is killed, clear the pet info from char sheet
-	/*if (dead->IsNPC() && ((NPC*)dead)->IsPet() && ((NPC*)dead)->GetOwner()->IsPlayer())
-		((Player*)((NPC*)dead)->GetOwner())->ResetPetInfo();*/
-
 	safe_delete(encounter);
 }