/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "ObjectAccessor.h" #include "Corpse.h" #include "Creature.h" #include "DynamicObject.h" #include "GameObject.h" #include "GridNotifiers.h" #include "Item.h" #include "Map.h" #include "ObjectMgr.h" #include "Pet.h" #include "Player.h" #include "Transport.h" #include template void HashMapHolder::Insert(T* o) { static_assert(std::is_same::value, "Only Player can be registered in global HashMapHolder"); std::unique_lock lock(*GetLock()); GetContainer()[o->GetGUID()] = o; } template void HashMapHolder::Remove(T* o) { std::unique_lock lock(*GetLock()); GetContainer().erase(o->GetGUID()); } template T* HashMapHolder::Find(ObjectGuid guid) { std::shared_lock lock(*GetLock()); typename MapType::iterator itr = GetContainer().find(guid); return (itr != GetContainer().end()) ? itr->second : nullptr; } template auto HashMapHolder::GetContainer() -> MapType& { static MapType _objectMap; return _objectMap; } template std::shared_mutex* HashMapHolder::GetLock() { static std::shared_mutex _lock; return &_lock; } template class TC_GAME_API HashMapHolder; namespace PlayerNameMapHolder { typedef std::unordered_map MapType; static MapType PlayerNameMap; void Insert(Player* p) { PlayerNameMap[p->GetName()] = p; } void Remove(Player* p) { PlayerNameMap.erase(p->GetName()); } Player* Find(std::string_view name) { std::string charName(name); if (!normalizePlayerName(charName)) return nullptr; auto itr = PlayerNameMap.find(charName); return (itr != PlayerNameMap.end()) ? itr->second : nullptr; } } // namespace PlayerNameMapHolder WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid const& guid) { switch (guid.GetHigh()) { case HighGuid::Player: return GetPlayer(p, guid); case HighGuid::Transport: case HighGuid::GameObject: return GetGameObject(p, guid); case HighGuid::Vehicle: case HighGuid::Creature: return GetCreature(p, guid); case HighGuid::Pet: return GetPet(p, guid); case HighGuid::DynamicObject: return GetDynamicObject(p, guid); case HighGuid::AreaTrigger: return GetAreaTrigger(p, guid); case HighGuid::Corpse: return GetCorpse(p, guid); case HighGuid::SceneObject: return GetSceneObject(p, guid); case HighGuid::Conversation: return GetConversation(p, guid); default: return nullptr; } } Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid const& guid, uint32 typemask) { switch (guid.GetHigh()) { case HighGuid::Item: if (typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER) return static_cast(p).GetItemByGuid(guid); break; case HighGuid::Player: if (typemask & TYPEMASK_PLAYER) return GetPlayer(p, guid); break; case HighGuid::Transport: case HighGuid::GameObject: if (typemask & TYPEMASK_GAMEOBJECT) return GetGameObject(p, guid); break; case HighGuid::Creature: case HighGuid::Vehicle: if (typemask & TYPEMASK_UNIT) return GetCreature(p, guid); break; case HighGuid::Pet: if (typemask & TYPEMASK_UNIT) return GetPet(p, guid); break; case HighGuid::DynamicObject: if (typemask & TYPEMASK_DYNAMICOBJECT) return GetDynamicObject(p, guid); break; case HighGuid::AreaTrigger: if (typemask & TYPEMASK_AREATRIGGER) return GetAreaTrigger(p, guid); break; case HighGuid::SceneObject: if (typemask & TYPEMASK_SCENEOBJECT) return GetSceneObject(p, guid); break; case HighGuid::Conversation: if (typemask & TYPEMASK_CONVERSATION) return GetConversation(p, guid); break; case HighGuid::Corpse: if (typemask & TYPEMASK_CORPSE) return GetCorpse(p, guid); break; default: break; } return nullptr; } Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, ObjectGuid const& guid) { return u.GetMap()->GetCorpse(guid); } GameObject* ObjectAccessor::GetGameObject(WorldObject const& u, ObjectGuid const& guid) { return u.GetMap()->GetGameObject(guid); } Transport* ObjectAccessor::GetTransport(WorldObject const& u, ObjectGuid const& guid) { return u.GetMap()->GetTransport(guid); } DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, ObjectGuid const& guid) { return u.GetMap()->GetDynamicObject(guid); } AreaTrigger* ObjectAccessor::GetAreaTrigger(WorldObject const& u, ObjectGuid const& guid) { return u.GetMap()->GetAreaTrigger(guid); } SceneObject* ObjectAccessor::GetSceneObject(WorldObject const& u, ObjectGuid const& guid) { return u.GetMap()->GetSceneObject(guid); } Conversation* ObjectAccessor::GetConversation(WorldObject const& u, ObjectGuid const& guid) { return u.GetMap()->GetConversation(guid); } Unit* ObjectAccessor::GetUnit(WorldObject const& u, ObjectGuid const& guid) { if (guid.IsPlayer()) return GetPlayer(u, guid); if (guid.IsPet()) return GetPet(u, guid); return GetCreature(u, guid); } Creature* ObjectAccessor::GetCreature(WorldObject const& u, ObjectGuid const& guid) { return u.GetMap()->GetCreature(guid); } Pet* ObjectAccessor::GetPet(WorldObject const& u, ObjectGuid const& guid) { return u.GetMap()->GetPet(guid); } Player* ObjectAccessor::GetPlayer(Map const* m, ObjectGuid const& guid) { if (Player* player = HashMapHolder::Find(guid)) if (player->IsInWorld() && player->GetMap() == m) return player; return nullptr; } Player* ObjectAccessor::GetPlayer(WorldObject const& u, ObjectGuid const& guid) { return GetPlayer(u.GetMap(), guid); } Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, ObjectGuid const& guid) { if (guid.IsPet()) return GetPet(u, guid); if (guid.IsCreatureOrVehicle()) return GetCreature(u, guid); return nullptr; } Player* ObjectAccessor::FindPlayer(ObjectGuid const& guid) { Player* player = HashMapHolder::Find(guid); return player && player->IsInWorld() ? player : nullptr; } Player* ObjectAccessor::FindPlayerByName(std::string_view name) { Player* player = PlayerNameMapHolder::Find(name); if (!player || !player->IsInWorld()) return nullptr; return player; } Player* ObjectAccessor::FindPlayerByLowGUID(ObjectGuid::LowType lowguid) { ObjectGuid guid = ObjectGuid::Create(lowguid); return ObjectAccessor::FindPlayer(guid); } Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid const& guid) { return HashMapHolder::Find(guid); } Player* ObjectAccessor::FindConnectedPlayerByName(std::string_view name) { return PlayerNameMapHolder::Find(name); } HashMapHolder::MapType const& ObjectAccessor::GetPlayers() { return HashMapHolder::GetContainer(); } void ObjectAccessor::SaveAllPlayers() { std::shared_lock lock(*HashMapHolder::GetLock()); HashMapHolder::MapType const& m = GetPlayers(); for (HashMapHolder::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) itr->second->SaveToDB(); } template<> void ObjectAccessor::AddObject(Player* player) { HashMapHolder::Insert(player); PlayerNameMapHolder::Insert(player); } template<> void ObjectAccessor::RemoveObject(Player* player) { HashMapHolder::Remove(player); PlayerNameMapHolder::Remove(player); }