*Cleanup in ObjectAccessor - this should fix some crashes

--HG--
branch : trunk
This commit is contained in:
QAston
2010-07-28 00:08:21 +02:00
parent 51400a4e15
commit e232c0e235
13 changed files with 123 additions and 160 deletions
@@ -85,12 +85,7 @@ void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
// Possible crash at access to deleted GO in Unit::m_gameobj
if (uint64 owner_guid = GetOwnerGUID())
{
Unit* owner = NULL;
// Object may be deleted while player is not in world, skip this check for now.
/*if (IS_PLAYER_GUID(owner_guid))
owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL);
else*/
owner = ObjectAccessor::GetUnit(*this,owner_guid);
Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid);
if (owner)
owner->RemoveGameObject(this,false);
@@ -133,9 +128,9 @@ void GameObject::RemoveFromWorld()
// Possible crash at access to deleted GO in Unit::m_gameobj
if (uint64 owner_guid = GetOwnerGUID())
{
if (Unit * owner = GetOwner(false))
if (Unit * owner = GetOwner())
owner->RemoveGameObject(this,false);
else if (!IS_PLAYER_GUID(owner_guid))
else
sLog.outError("Delete GameObject (GUID: %u Entry: %u) that have references in not found creature %u GO list. Crash possible later.",GetGUIDLow(),GetGOInfo()->id,GUID_LOPART(owner_guid));
}
WorldObject::RemoveFromWorld();
@@ -490,7 +485,7 @@ void GameObject::Update(uint32 diff)
if (GetOwnerGUID())
{
if (Unit* owner = GetOwner(false))
if (Unit* owner = GetOwner())
{
owner->RemoveGameObject(this, false);
SetRespawnTime(0);
@@ -553,7 +548,7 @@ void GameObject::Delete()
{
SetLootState(GO_NOT_READY);
if (GetOwnerGUID())
if (Unit * owner = GetOwner(false))
if (Unit * owner = GetOwner())
owner->RemoveGameObject(this, false);
assert (!GetOwnerGUID());
@@ -776,11 +771,9 @@ bool GameObject::IsDynTransport() const
}
Unit* GameObject::GetOwner(bool inWorld) const
Unit* GameObject::GetOwner() const
{
if (inWorld)
return ObjectAccessor::GetUnit(*this, GetOwnerGUID());
return ObjectAccessor::GetUnitInOrOutOfWorld(*this, GetOwnerGUID());
return ObjectAccessor::GetUnit(*this, GetOwnerGUID());
}
void GameObject::SaveRespawnTime()
@@ -640,7 +640,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>
SetUInt64Value(OBJECT_FIELD_CREATED_BY, owner);
}
uint64 GetOwnerGUID() const { return GetUInt64Value(OBJECT_FIELD_CREATED_BY); }
Unit* GetOwner(bool inWorld = true) const;
Unit* GetOwner() const;
void SetSpellId(uint32 id)
{
+1 -1
View File
@@ -18526,7 +18526,7 @@ Pet* Player::GetPet() const
if (!IS_PET_GUID(pet_guid))
return NULL;
Pet* pet = ObjectAccessor::GetPet(pet_guid);
Pet* pet = ObjectAccessor::GetPet(*this, pet_guid);
if (!pet)
return NULL;
+2 -4
View File
@@ -9400,13 +9400,11 @@ bool Unit::HasAuraState(AuraState flag, SpellEntry const *spellProto, Unit const
return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
}
Unit *Unit::GetOwner(bool inWorld) const
Unit *Unit::GetOwner() const
{
if (uint64 ownerid = GetOwnerGUID())
{
if (inWorld)
return ObjectAccessor::GetUnit(*this, ownerid);
return ObjectAccessor::GetUnitInOrOutOfWorld(*this, ownerid);
return ObjectAccessor::GetUnit(*this, ownerid);
}
return NULL;
}
+1 -1
View File
@@ -1492,7 +1492,7 @@ class Unit : public WorldObject
Player* GetSpellModOwner() const;
Unit* GetOwner(bool inWorld = true) const;
Unit* GetOwner() const;
Guardian *GetGuardianPet() const;
Minion *GetFirstMinion() const;
Unit* GetCharmer() const;
+62 -47
View File
@@ -54,43 +54,16 @@ ObjectAccessor::~ObjectAccessor()
}
}
Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, uint64 guid)
{
if (IS_PLAYER_GUID(guid))
return NULL;
if (IS_PET_GUID(guid))
return GetPet(guid);
return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL;
}
Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, uint64 guid)
{
Corpse* ret = GetObjectInWorld(guid, (Corpse*)NULL);
if (!ret)
return NULL;
if (ret->GetMapId() != u.GetMapId())
return NULL;
if (ret->GetInstanceId() != u.GetInstanceId())
return NULL;
return ret;
}
WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, uint64 guid)
{
switch (GUID_HIPART(guid))
{
case HIGHGUID_PLAYER: return FindPlayer(guid);
case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid);
case HIGHGUID_PLAYER: return GetPlayer(p, guid);
case HIGHGUID_GAMEOBJECT: return GetGameObject(p, guid);
case HIGHGUID_VEHICLE:
case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid);
case HIGHGUID_PET: return GetPet(guid);
case HIGHGUID_DYNAMICOBJECT: return p.GetMap()->GetDynamicObject(guid);
case HIGHGUID_UNIT: return GetCreature(p, guid);
case HIGHGUID_PET: return GetPet(p, guid);
case HIGHGUID_DYNAMICOBJECT: return GetDynamicObject(p, guid);
case HIGHGUID_TRANSPORT: return NULL;
case HIGHGUID_CORPSE: return GetCorpse(p,guid);
case HIGHGUID_MO_TRANSPORT: return NULL;
@@ -108,24 +81,24 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, uint64 guid, u
break;
case HIGHGUID_PLAYER:
if (typemask & TYPEMASK_PLAYER)
return FindPlayer(guid);
return GetPlayer(p, guid);
break;
case HIGHGUID_GAMEOBJECT:
if (typemask & TYPEMASK_GAMEOBJECT)
return p.GetMap()->GetGameObject(guid);
return GetGameObject(p, guid);
break;
case HIGHGUID_UNIT:
case HIGHGUID_VEHICLE:
if (typemask & TYPEMASK_UNIT)
return p.GetMap()->GetCreature(guid);
return GetCreature(p, guid);
break;
case HIGHGUID_PET:
if (typemask & TYPEMASK_UNIT)
return GetPet(guid);
return GetPet(p, guid);
break;
case HIGHGUID_DYNAMICOBJECT:
if (typemask & TYPEMASK_DYNAMICOBJECT)
return p.GetMap()->GetDynamicObject(guid);
return GetDynamicObject(p, guid);
break;
case HIGHGUID_TRANSPORT:
case HIGHGUID_CORPSE:
@@ -136,13 +109,60 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, uint64 guid, u
return NULL;
}
Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, uint64 guid)
{
return GetObjectInMap(guid, u.GetMap(), (Corpse*)NULL);
}
GameObject* ObjectAccessor::GetGameObject(WorldObject const& u, uint64 guid)
{
return GetObjectInMap(guid, u.GetMap(), (GameObject*)NULL);
}
DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, uint64 guid)
{
return GetObjectInMap(guid, u.GetMap(), (DynamicObject*)NULL);
}
Unit* ObjectAccessor::GetUnit(WorldObject const& u, uint64 guid)
{
return GetObjectInMap(guid, u.GetMap(), (Unit*)NULL);
}
Creature* ObjectAccessor::GetCreature(WorldObject const& u, uint64 guid)
{
return GetObjectInMap(guid, u.GetMap(), (Creature*)NULL);
}
Pet* ObjectAccessor::GetPet(WorldObject const& u, uint64 guid)
{
return GetObjectInMap(guid, u.GetMap(), (Pet*)NULL);
}
Player* ObjectAccessor::GetPlayer(WorldObject const& u, uint64 guid)
{
return GetObjectInMap(guid, u.GetMap(), (Player*)NULL);
}
Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, uint64 guid)
{
if (IS_PET_GUID(guid))
return GetPet(u, guid);
if (IS_CRE_OR_VEH_GUID(guid))
return GetCreature(u, guid);
return NULL;
}
Pet* ObjectAccessor::FindPet(uint64 guid)
{
return GetObjectInWorld(guid, (Pet*)NULL);
}
Player* ObjectAccessor::FindPlayer(uint64 guid)
{
Player* plr = GetObjectInWorld(guid, (Player*)NULL);
if (!plr || !plr->IsInWorld())
return NULL;
return plr;
return GetObjectInWorld(guid, (Player*)NULL);
}
Player* ObjectAccessor::FindPlayerByName(const char* name)
@@ -164,11 +184,6 @@ void ObjectAccessor::SaveAllPlayers()
itr->second->SaveToDB();
}
Pet* ObjectAccessor::GetPet(uint64 guid)
{
return GetObjectInWorld(guid, (Pet*)NULL);
}
Corpse* ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
{
ACE_GUARD_RETURN(LockType, guard, i_corpseGuard, NULL);
+39 -38
View File
@@ -40,6 +40,7 @@ class Unit;
class GameObject;
class DynamicObject;
class WorldObject;
class Vehicle;
class Map;
template <class T>
@@ -95,47 +96,42 @@ class ObjectAccessor
typedef UNORDERED_MAP<uint64, Corpse*> Player2CorpsesMapType;
typedef UNORDERED_MAP<Player*, UpdateData>::value_type UpdateDataValueType;
template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
// TODO: override these template functions for each holder type and add assertions
// returns object if is in world
template<class T> static T* GetObjectInWorld(uint64 guid, T* /*typeSpecifier*/)
{
return HashMapHolder<T>::Find(guid);
}
static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/)
// Player may be not in world while in ObjectAccessor
static Player* GetObjectInWorld(uint64 guid, Player* /*typeSpecifier*/)
{
if (!guid)
return NULL;
if (IS_PLAYER_GUID(guid))
{
Unit* u = (Unit*)HashMapHolder<Player>::Find(guid);
if (!u || !u->IsInWorld())
return NULL;
return u;
}
if (IS_PET_GUID(guid))
return (Unit*)HashMapHolder<Pet>::Find(guid);
return (Unit*)HashMapHolder<Creature>::Find(guid);
Player * player = HashMapHolder<Player>::Find(guid);
if (player && player->IsInWorld())
return player;
return NULL;
}
static Unit* GetUnitInOrOutOfWorld(uint64 guid, Unit* /*fake*/)
static Unit* GetObjectInWorld(uint64 guid, Unit* /*typeSpecifier*/)
{
if (!guid)
return NULL;
if (IS_PLAYER_GUID(guid))
{
Unit* u = (Unit*)HashMapHolder<Player>::Find(guid);
if (!u)
return NULL;
return (Unit*)GetObjectInWorld(guid, (Player*)NULL);
return u;
}
if (IS_PET_GUID(guid))
return (Unit*)GetObjectInWorld(guid, (Pet*)NULL);
// Other object types than player are unloaded while out of world
return GetObjectInWorld(guid, (Unit*)NULL);
return (Unit*)GetObjectInWorld(guid, (Creature*)NULL);
}
// returns object if is in map
template<class T> static T* GetObjectInMap(uint64 guid, Map * map, T* /*typeSpecifier*/)
{
assert(map);
if (T * obj = GetObjectInWorld(guid, (T*)NULL))
if (obj->GetMap() == map)
return obj;
return NULL;
}
template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/)
@@ -167,18 +163,23 @@ class ObjectAccessor
return NULL;
}
// these functions return objects only if in map of specified object
static WorldObject* GetWorldObject(WorldObject const&, uint64);
static Object* GetObjectByTypeMask(WorldObject const&, uint64, uint32 typemask);
static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, uint64);
static Unit* GetUnit(WorldObject const&, uint64 guid) { return GetObjectInWorld(guid, (Unit*)NULL); }
static Unit* GetUnitInOrOutOfWorld(WorldObject const&, uint64 guid) { return GetUnitInOrOutOfWorld(guid, (Unit*)NULL); }
static Pet* GetPet(Unit const&, uint64 guid) { return GetPet(guid); }
static Player* GetPlayer(Unit const&, uint64 guid) { return FindPlayer(guid); }
static Corpse* GetCorpse(WorldObject const& u, uint64 guid);
static Pet* GetPet(uint64 guid);
static Player* FindPlayer(uint64);
static GameObject* GetGameObject(WorldObject const& u, uint64 guid);
static DynamicObject* GetDynamicObject(WorldObject const& u, uint64 guid);
static Unit* GetUnit(WorldObject const&, uint64 guid);
static Creature* GetCreature(WorldObject const& u, uint64 guid);
static Pet* GetPet(WorldObject const&, uint64 guid);
static Player* GetPlayer(WorldObject const&, uint64 guid);
static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, uint64);
Player* FindPlayerByName(const char* name) ;
// these functions return objects if found in whole world
// ACCESS LIKE THAT IS NOT THREAD SAFE
static Pet * FindPet(uint64);
static Player* FindPlayer(uint64);
Player* FindPlayerByName(const char* name);
// when using this, you must use the hashmapholder's lock
HashMapHolder<Player>::MapType& GetPlayers()
+3 -30
View File
@@ -3942,46 +3942,19 @@ void Map::ScriptsProcess()
Creature*
Map::GetCreature(uint64 guid)
{
Creature * ret = NULL;
if (IS_CRE_OR_VEH_GUID(guid))
ret = ObjectAccessor::GetObjectInWorld(guid, (Creature*)NULL);
if (!ret)
return NULL;
if (ret->GetMapId() != GetId())
return NULL;
if (ret->GetInstanceId() != GetInstanceId())
return NULL;
return ret;
return ObjectAccessor::GetObjectInMap(guid, this, (Creature*)NULL);
}
GameObject*
Map::GetGameObject(uint64 guid)
{
GameObject * ret = ObjectAccessor::GetObjectInWorld(guid, (GameObject*)NULL);
if (!ret)
return NULL;
if (ret->GetMapId() != GetId())
return NULL;
if (ret->GetInstanceId() != GetInstanceId())
return NULL;
return ret;
return ObjectAccessor::GetObjectInMap(guid, this, (GameObject*)NULL);
}
DynamicObject*
Map::GetDynamicObject(uint64 guid)
{
DynamicObject * ret = ObjectAccessor::GetObjectInWorld(guid, (DynamicObject*)NULL);
if (!ret)
return NULL;
if (ret->GetMapId() != GetId())
return NULL;
if (ret->GetInstanceId() != GetInstanceId())
return NULL;
return ret;
return ObjectAccessor::GetObjectInMap(guid, this, (DynamicObject*)NULL);
}
void Map::UpdateIteratorBack(Player *player)
+4 -4
View File
@@ -273,12 +273,12 @@ bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standi
else
{
// update for the actual faction first
bool res = SetOneFactionReputation(factionEntry, standing, incremental);
bool res = SetOneFactionReputation(factionEntry, standing, incremental);
if (res)
{
// then some spillover calculation here if it exist
if (const RepSpilloverTemplate *repTemplate = objmgr.GetRepSpilloverTemplate(factionEntry->ID))
if (RepSpilloverTemplate const * repTemplate = objmgr.GetRepSpilloverTemplate(factionEntry->ID))
{
for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i)
{
@@ -287,7 +287,7 @@ bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standi
if (m_player->GetReputationRank(repTemplate->faction[i]) <= ReputationRank(repTemplate->faction_rank[i]))
{
// bonuses are already given, so just modify standing by rate
int32 spilloverRep = standing * repTemplate->faction_rate[i];
int32 spilloverRep = standing * repTemplate->faction_rate[i];
SetOneFactionReputation(sFactionStore.LookupEntry(repTemplate->faction[i]), spilloverRep, incremental);
}
}
@@ -295,7 +295,7 @@ bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standi
}
// now we can send it
FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
if (itr != m_factions.end())
SendState(&itr->second);
}
@@ -557,7 +557,7 @@ void WorldSession::HandlePetRename(WorldPacket & recv_data)
recv_data >> name;
recv_data >> isdeclined;
Pet* pet = ObjectAccessor::GetPet(petguid);
Pet* pet = ObjectAccessor::FindPet(petguid);
// check it!
if (!pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET ||
!pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ||
-17
View File
@@ -1046,23 +1046,6 @@ void Spell::AddItemTarget(Item* pitem, uint32 effIndex)
void Spell::DoAllEffectOnTarget(TargetInfo *target)
{
// invalid pointer, log debug info to trac the reason
if (target && target < ((TargetInfo*)1024))
{
sLog.outString("Spell::DoAllEffectOnTarget CRASH! - debug info:");
sLog.outString("Caster:");
m_caster->OutDebugInfo();
if (m_targets.getUnitTarget())
{
sLog.outString("Unit target:");
m_targets.getUnitTarget()->OutDebugInfo();
}
sLog.outString("SpellId: %d", m_spellInfo->Id);
sLog.outString("SpellTargetMap:");
for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
sLog.outStringInLine("guid:%u, effmask:%u, ", ihit->targetGUID, ihit->effectMask);
ASSERT(false);
}
if (!target || target->processed)
return;
@@ -2017,7 +2017,7 @@ struct npc_seaforium_depth_chargeAI : public ScriptedAI
{
if (Creature* cCredit = me->FindNearestCreature(25402 + i, 10.0f))//25402-25405 credit markers
{
if (Unit* uOwner = me->GetOwner(true))
if (Unit* uOwner = me->GetOwner())
{
Player* pOwner = uOwner->ToPlayer();
if (pOwner && pOwner->GetQuestStatus(QUEST_BURY_THOSE_COCKROACHES) == QUEST_STATUS_INCOMPLETE)
+1 -1
View File
@@ -753,7 +753,7 @@ bool GOHello_go_inconspicuous_landmark(Player *pPlayer, GameObject* /*pGO*/)
bool GOHello_go_soulwell(Player *pPlayer, GameObject* pGO)
{
Unit *caster = pGO->GetOwner(false);
Unit *caster = pGO->GetOwner();
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
return true;