diff --git a/src/framework/GameSystem/TypeContainer.h b/src/framework/GameSystem/TypeContainer.h index 894027c2f..2b46ff67b 100644 --- a/src/framework/GameSystem/TypeContainer.h +++ b/src/framework/GameSystem/TypeContainer.h @@ -28,8 +28,114 @@ #include #include "Platform/Define.h" #include "Utilities/TypeList.h" +#include "Utilities/UnorderedMap.h" #include "GameSystem/GridRefManager.h" +template struct ContainerUnorderedMap +{ + UNORDERED_MAP _element; +}; +template struct ContainerUnorderedMap +{ +}; +template struct ContainerUnorderedMap< TypeList, KEY_TYPE > +{ + ContainerUnorderedMap _elements; + ContainerUnorderedMap _TailElements; +}; + +template +class TypeUnorderedMapContainer +{ + public: + template bool insert(KEY_TYPE handle, SPECIFIC_TYPE* obj) + { + return TypeUnorderedMapContainer::insert(i_elements, handle, obj); + } + template bool erase(KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/) + { + return TypeUnorderedMapContainer::erase(i_elements, handle, (SPECIFIC_TYPE*)NULL); + } + template SPECIFIC_TYPE* find(KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/) + { + return TypeUnorderedMapContainer::find(i_elements, hdl, (SPECIFIC_TYPE*)NULL); + } + private: + ContainerUnorderedMap i_elements; + + // Helpers + // Insert helpers + template static bool insert(ContainerUnorderedMap& elements, KEY_TYPE handle, SPECIFIC_TYPE* obj) + { + typename UNORDERED_MAP::iterator i = elements._element.find(handle); + if (i == elements._element.end()) + { + elements._element[handle] = obj; + return true; + } + else + { + assert (i->second == obj && "Object with certain key already in but objects are different!"); + return false; + } + } + template static bool insert(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + template static bool insert(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + template static bool insert(ContainerUnorderedMap< TypeList, KEY_TYPE >& elements, KEY_TYPE handle, SPECIFIC_TYPE* obj) + { + bool ret = TypeUnorderedMapContainer::insert(elements._elements, handle, obj); + return ret ? ret : TypeUnorderedMapContainer::insert(elements._TailElements, handle, obj); + } + // Find helpers + template static SPECIFIC_TYPE* find(ContainerUnorderedMap& elements, KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/) + { + typename UNORDERED_MAP::iterator i = elements._element.find(hdl); + if (i == elements._element.end()) + return NULL; + else + return i->second; + } + template static SPECIFIC_TYPE* find(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*hdl*/, SPECIFIC_TYPE* /*obj*/) + { + return NULL; + } + template static SPECIFIC_TYPE* find(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*hdl*/, SPECIFIC_TYPE* /*obj*/) + { + return NULL; + } + template static SPECIFIC_TYPE* find(ContainerUnorderedMap< TypeList, KEY_TYPE >& elements, KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/) + { + SPECIFIC_TYPE* ret = TypeUnorderedMapContainer::find(elements._elements, hdl, (SPECIFIC_TYPE*)NULL); + return ret ? ret : TypeUnorderedMapContainer::find(elements._TailElements, hdl, (SPECIFIC_TYPE*)NULL); + } + // Erase helpers + template static bool erase(ContainerUnorderedMap& elements, KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/) + { + elements._element.erase(handle); + + return true; + } + template static bool erase(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + template static bool erase(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + template static bool erase(ContainerUnorderedMap< TypeList, KEY_TYPE >& elements, KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/) + { + bool ret = TypeUnorderedMapContainer::erase(elements._elements, handle, (SPECIFIC_TYPE*)NULL); + return ret ? ret : TypeUnorderedMapContainer::erase(elements._TailElements, handle, (SPECIFIC_TYPE*)NULL); + } +}; + /* * @class ContainerMapList is a mulit-type container for map elements * By itself its meaningless but collaborate along with TypeContainers, diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index b21bb0571..a9503f720 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -1808,6 +1808,8 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList() if(!criteria) continue; + assert(criteria->requiredType < ACHIEVEMENT_CRITERIA_TYPE_TOTAL && "Not updated ACHIEVEMENT_CRITERIA_TYPE_TOTAL?"); + m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria); } diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp index ad485cdb8..8a7ed49e8 100644 --- a/src/game/BattleGroundAB.cpp +++ b/src/game/BattleGroundAB.cpp @@ -26,6 +26,7 @@ #include "Language.h" #include "Util.h" #include "WorldPacket.h" +#include "MapManager.h" BattleGroundAB::BattleGroundAB() { diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp index f3ef573f2..cab99dec5 100644 --- a/src/game/BattleGroundEY.cpp +++ b/src/game/BattleGroundEY.cpp @@ -26,6 +26,7 @@ #include "Language.h" #include "WorldPacket.h" #include "Util.h" +#include "MapManager.h" BattleGroundEY::BattleGroundEY() { diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp index 296e79875..c4ad4efbd 100644 --- a/src/game/BattleGroundWS.cpp +++ b/src/game/BattleGroundWS.cpp @@ -26,6 +26,7 @@ #include "BattleGroundMgr.h" #include "WorldPacket.h" #include "Language.h" +#include "MapManager.h" BattleGroundWS::BattleGroundWS() { diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index b9ce2442a..fc2ab843b 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -141,14 +141,18 @@ Creature::~Creature() void Creature::AddToWorld() { ///- Register the creature for guid lookup - if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + if(!IsInWorld()) + GetMap()->GetObjectsStore().insert(GetGUID(), (Creature*)this); + Unit::AddToWorld(); } void Creature::RemoveFromWorld() { ///- Remove the creature from the accessor - if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + if(IsInWorld()) + GetMap()->GetObjectsStore().erase(GetGUID(), (Creature*)NULL); + Unit::RemoveFromWorld(); } diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 92db7e25b..f6bbaf742 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -41,7 +41,7 @@ void DynamicObject::AddToWorld() { ///- Register the dynamicObject for guid lookup if(!IsInWorld()) - ObjectAccessor::Instance().AddObject(this); + GetMap()->GetObjectsStore().insert(GetGUID(), (DynamicObject*)this); Object::AddToWorld(); } @@ -50,7 +50,7 @@ void DynamicObject::RemoveFromWorld() { ///- Remove the dynamicObject from the accessor if(IsInWorld()) - ObjectAccessor::Instance().RemoveObject(this); + GetMap()->GetObjectsStore().erase(GetGUID(), (DynamicObject*)NULL); Object::RemoveFromWorld(); } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index c7d1829a7..e5253fae5 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -60,23 +60,26 @@ GameObject::GameObject() : WorldObject() GameObject::~GameObject() { - CleanupsBeforeDelete(); } -void GameObject::CleanupsBeforeDelete() +void GameObject::AddToWorld() { - if(m_uint32Values) // field array can be not exist if GameOBject not loaded + ///- Register the gameobject for guid lookup + if(!IsInWorld()) + GetMap()->GetObjectsStore().insert(GetGUID(), (GameObject*)this); + + Object::AddToWorld(); +} + +void GameObject::RemoveFromWorld() +{ + ///- Remove the gameobject from the accessor + if(IsInWorld()) { - // Possible crash at access to deleted GO in Unit::m_gameobj + // Remove GO from owner if(uint64 owner_guid = GetOwnerGUID()) { - Unit* owner = NULL; - if(IS_PLAYER_GUID(owner_guid)) - owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL); - else - owner = ObjectAccessor::GetUnit(*this,owner_guid); - - if(owner) + if (Unit* owner = IS_PLAYER_GUID(owner_guid) ? ObjectAccessor::FindPlayer(owner_guid) : GetMap()->GetCreatureOrPet(owner_guid)) owner->RemoveGameObject(this,false); else { @@ -90,20 +93,10 @@ void GameObject::CleanupsBeforeDelete() GetGUIDLow(), GetGOInfo()->id, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType); } } + + GetMap()->GetObjectsStore().erase(GetGUID(), (GameObject*)NULL); } -} -void GameObject::AddToWorld() -{ - ///- Register the gameobject for guid lookup - if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); - Object::AddToWorld(); -} - -void GameObject::RemoveFromWorld() -{ - ///- Remove the gameobject from the accessor - if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); Object::RemoveFromWorld(); } @@ -700,6 +693,10 @@ bool GameObject::isVisibleForInState(Player const* u, WorldObject const* viewPoi if(!IsInWorld() || !u->IsInWorld()) return false; + // invisible at client always + if(!GetGOInfo()->displayId) + return false; + // Transport always visible at this step implementation if(IsTransport() && IsInMap(u)) return true; diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 06ebfa278..db0a49665 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -559,7 +559,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject void AddToWorld(); void RemoveFromWorld(); - void CleanupsBeforeDelete(); bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state); void Update(uint32 p_time); diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h index 7d57814fb..ebfbf20dd 100644 --- a/src/game/GridDefines.h +++ b/src/game/GridDefines.h @@ -26,6 +26,7 @@ // Forward class definitions class Corpse; class Creature; +class Vehicle; class DynamicObject; class GameObject; class Pet; @@ -57,6 +58,7 @@ class Player; // Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case) typedef TYPELIST_3(Player, Creature/*pets*/, Corpse/*resurrectable*/) AllWorldObjectTypes; typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes; +typedef TYPELIST_5(Creature, Pet, Vehicle, GameObject, DynamicObject) AllMapStoredObjectTypes; typedef GridRefManager CorpseMapType; typedef GridRefManager CreatureMapType; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 52a57efaf..4abed7b57 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -56,6 +56,7 @@ struct ScriptAction Map::~Map() { + ObjectAccessor::DelinkMap(this); UnloadAll(true); if(!m_scriptSchedule.empty()) @@ -212,6 +213,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par setNGrid(NULL, idx, j); } } + ObjectAccessor::LinkMap(this); //lets initialize visibility distance for map Map::InitVisibilityDistance(); @@ -2761,19 +2763,19 @@ void Map::ScriptsProcess() break; } case HIGHGUID_UNIT: - source = HashMapHolder::Find(step.sourceGUID); + source = GetCreature(step.sourceGUID); break; case HIGHGUID_PET: - source = HashMapHolder::Find(step.sourceGUID); + source = GetPet(step.sourceGUID); break; case HIGHGUID_VEHICLE: - source = HashMapHolder::Find(step.sourceGUID); + source = GetVehicle(step.sourceGUID); break; case HIGHGUID_PLAYER: source = HashMapHolder::Find(step.sourceGUID); break; case HIGHGUID_GAMEOBJECT: - source = HashMapHolder::Find(step.sourceGUID); + source = GetGameObject(step.sourceGUID); break; case HIGHGUID_CORPSE: source = HashMapHolder::Find(step.sourceGUID); @@ -2793,19 +2795,19 @@ void Map::ScriptsProcess() switch(GUID_HIPART(step.targetGUID)) { case HIGHGUID_UNIT: - target = HashMapHolder::Find(step.targetGUID); + target = GetCreature(step.targetGUID); break; case HIGHGUID_PET: - target = HashMapHolder::Find(step.targetGUID); + target = GetPet(step.targetGUID); break; case HIGHGUID_VEHICLE: - target = HashMapHolder::Find(step.targetGUID); + target = GetVehicle(step.targetGUID); break; case HIGHGUID_PLAYER: // empty GUID case also target = HashMapHolder::Find(step.targetGUID); break; case HIGHGUID_GAMEOBJECT: - target = HashMapHolder::Find(step.targetGUID); + target = GetGameObject(step.targetGUID); break; case HIGHGUID_CORPSE: target = HashMapHolder::Find(step.targetGUID); @@ -3381,44 +3383,35 @@ void Map::ScriptsProcess() return; } -Creature* -Map::GetCreature(uint64 guid) +Creature* Map::GetCreature(uint64 guid) { - Creature * 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 m_objectsStore.find(guid, (Creature*)NULL); } -GameObject* -Map::GetGameObject(uint64 guid) +Vehicle* Map::GetVehicle(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 m_objectsStore.find(guid, (Vehicle*)NULL); } -DynamicObject* -Map::GetDynamicObject(uint64 guid) +Pet* Map::GetPet(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 m_objectsStore.find(guid, (Pet*)NULL); +} + +Unit* Map::GetCreatureOrPet(uint64 guid) +{ + if (Unit* ret = GetCreature(guid)) + return ret; + + return GetPet(guid); +} + +GameObject* Map::GetGameObject(uint64 guid) +{ + return m_objectsStore.find(guid, (GameObject*)NULL); +} + +DynamicObject* Map::GetDynamicObject(uint64 guid) +{ + return m_objectsStore.find(guid, (DynamicObject*)NULL); } diff --git a/src/game/Map.h b/src/game/Map.h index c867a31d5..a50a3e1f4 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -32,6 +32,7 @@ #include "SharedDefines.h" #include "GameSystem/GridRefManager.h" #include "MapRefManager.h" +#include "Utilities/TypeList.h" #include #include @@ -420,8 +421,13 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void RemoveFromActive(Creature* obj); Creature* GetCreature(uint64 guid); + Vehicle* GetVehicle(uint64 guid); + Pet* GetPet(uint64 guid); + Unit* GetCreatureOrPet(uint64 guid); GameObject* GetGameObject(uint64 guid); DynamicObject* GetDynamicObject(uint64 guid); + + TypeUnorderedMapContainer& GetObjectsStore() { return m_objectsStore; } private: void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); @@ -484,6 +490,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj typedef std::set ActiveNonPlayers; ActiveNonPlayers m_activeNonPlayers; ActiveNonPlayers::iterator m_activeNonPlayersIter; + TypeUnorderedMapContainer m_objectsStore; private: time_t i_gridExpiry; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 1a67a9df5..4c4926ec3 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -257,7 +257,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 { case TYPEID_UNIT: { - flags2 = ((Unit*)this)->isInFlight() ? (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_LEVITATING) : MOVEMENTFLAG_NONE; + flags2 = ((Creature*)this)->canFly() ? (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_LEVITATING) : MOVEMENTFLAG_NONE; } break; case TYPEID_PLAYER: diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 9604eee8f..1eb61903e 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -53,16 +53,16 @@ ObjectAccessor::~ObjectAccessor() Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid) { - if(IS_PLAYER_GUID(guid)) + if(IS_PLAYER_GUID(guid) || !u.IsInWorld()) return NULL; if(IS_PET_GUID(guid)) - return GetPet(guid); + return u.GetMap()->GetPet(guid); if(IS_VEHICLE_GUID(guid)) - return GetVehicle(guid); + return u.GetMap()->GetVehicle(guid); - return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL; + return u.GetMap()->GetCreature(guid); } Unit* @@ -97,8 +97,8 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const &p, uint64 guid) case HIGHGUID_PLAYER: return FindPlayer(guid); case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid); case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid); - case HIGHGUID_PET: return GetPet(guid); - case HIGHGUID_VEHICLE: return GetVehicle(guid); + case HIGHGUID_PET: return p.GetMap()->GetPet(guid); + case HIGHGUID_VEHICLE: return p.GetMap()->GetVehicle(guid); case HIGHGUID_DYNAMICOBJECT:return p.GetMap()->GetDynamicObject(guid); case HIGHGUID_TRANSPORT: return NULL; case HIGHGUID_CORPSE: return GetCorpse(p,guid); @@ -131,11 +131,11 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, u break; case HIGHGUID_PET: if(typemask & TYPEMASK_UNIT) - return GetPet(guid); + return p.GetMap()->GetPet(guid); break; case HIGHGUID_VEHICLE: if(typemask & TYPEMASK_UNIT) - return GetVehicle(guid); + return p.GetMap()->GetVehicle(guid); break; case HIGHGUID_DYNAMICOBJECT: if(typemask & TYPEMASK_DYNAMICOBJECT) @@ -175,7 +175,7 @@ ObjectAccessor::FindPlayerByName(const char *name) void ObjectAccessor::SaveAllPlayers() { - Guard guard(*HashMapHolder::GetLock()); + Guard guard(*HashMapHolder::GetLock()); HashMapHolder::MapType& m = HashMapHolder::GetContainer(); HashMapHolder::MapType::iterator itr = m.begin(); for(; itr != m.end(); ++itr) @@ -416,13 +416,11 @@ template ACE_Thread_Mutex HashMapHolder::i_lock; /// Global definitions for the hashmap storage template class HashMapHolder; -template class HashMapHolder; -template class HashMapHolder; -template class HashMapHolder; -template class HashMapHolder; -template class HashMapHolder; template class HashMapHolder; +/// Define the static member of ObjectAccessor +std::list ObjectAccessor::i_mapList; + template Player* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/); template Pet* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/); template Vehicle* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/); diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index e77b5abeb..7f6027dc1 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -32,6 +32,7 @@ #include "Player.h" #include +#include class Creature; class Corpse; @@ -95,29 +96,9 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton::Find(guid); } - static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/) - { - if(!guid) - return NULL; - - if (IS_PLAYER_GUID(guid)) - { - Unit * u = (Unit*)HashMapHolder::Find(guid); - if(!u || !u->IsInWorld()) - return NULL; - - return u; - } - - if (IS_PET_GUID(guid)) - return (Unit*)HashMapHolder::Find(guid); - - return (Unit*)HashMapHolder::Find(guid); - } - template static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/) { - T* obj = HashMapHolder::Find(guid); + T* obj = GetObjectInWorld(guid, (T*)NULL); if(!obj || obj->GetMapId() != mapid) return NULL; CellPair p = MaNGOS::ComputeCellPair(x,y); @@ -201,6 +182,9 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton void Visit(GridRefManager &) {} }; + // TODO: This methods will need lock in MT environment + // Theoreticaly multiple threads can enter and search in this method but + // in that case linking/delinking other map should be guarded + template static OBJECT* FindHelper(uint64 guid) + { + OBJECT* ret = NULL; + std::list::const_iterator i = i_mapList.begin(); + while (i != i_mapList.end() && !ret) + { + ret = (*i)->GetObjectsStore().find(guid, (OBJECT*)NULL); + ++i; + } + + return ret; + } + + static std::list i_mapList; + friend struct WorldObjectChangeAccumulator; Player2CorpsesMapType i_player2corpse; @@ -223,6 +225,52 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton inline Creature* ObjectAccessor::GetObjectInWorld(uint64 guid, Creature* /*fake*/) +{ + return FindHelper(guid); +} + +template <> inline GameObject* ObjectAccessor::GetObjectInWorld(uint64 guid, GameObject* /*fake*/) +{ + return FindHelper(guid); +} + +template <> inline DynamicObject* ObjectAccessor::GetObjectInWorld(uint64 guid, DynamicObject* /*fake*/) +{ + return FindHelper(guid); +} + +template <> inline Pet* ObjectAccessor::GetObjectInWorld(uint64 guid, Pet* /*fake*/) +{ + return FindHelper(guid); +} + +template <> inline Vehicle* ObjectAccessor::GetObjectInWorld(uint64 guid, Vehicle* /*fake*/) +{ + return FindHelper(guid); +} + +template <> inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/) +{ + if(!guid) + return NULL; + + if (IS_PLAYER_GUID(guid)) + { + Unit * u = (Unit*)HashMapHolder::Find(guid); + if(!u || !u->IsInWorld()) + return NULL; + + return u; + } + + if (IS_PET_GUID(guid)) + return (Unit*)GetObjectInWorld(guid, (Pet*)NULL); + + return (Unit*)GetObjectInWorld(guid, (Creature*)NULL); +} + #endif diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 8c3e089aa..22a46ae1f 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1228,11 +1228,18 @@ void ObjectMgr::LoadGameobjects() if(!gInfo->displayId) { - sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) doesn't have displayId (%u), not loaded.", guid, entry, gInfo->type, gInfo->displayId); - continue; + switch(gInfo->type) + { + // can be invisible always and then not req. display id in like case + case GAMEOBJECT_TYPE_TRAP: + case GAMEOBJECT_TYPE_SPELL_FOCUS: + break; + default: + sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have displayId == 0 and then will always invisible in game.", guid, entry, gInfo->type); + break; + } } - - if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId)) + else if (!sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId)) { sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have invalid displayId (%u), not loaded.", guid, entry, gInfo->type, gInfo->displayId); continue; diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 3581c456f..d1765c092 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -57,23 +57,24 @@ m_declinedname(NULL) Pet::~Pet() { - if(m_uint32Values) // only for fully created Object - ObjectAccessor::Instance().RemoveObject(this); - delete m_declinedname; } void Pet::AddToWorld() { ///- Register the pet for guid lookup - if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + if(!IsInWorld()) + GetMap()->GetObjectsStore().insert(GetGUID(), (Pet*)this); + Unit::AddToWorld(); } void Pet::RemoveFromWorld() { ///- Remove the pet from the accessor - if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + if(IsInWorld()) + GetMap()->GetObjectsStore().erase(GetGUID(), (Pet*)NULL); + ///- Don't call the function for Creature, normal mobs + totems go in a different storage Unit::RemoveFromWorld(); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 546856aa4..e99a08f4f 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6106,6 +6106,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor) if (uVictim != NULL) { honor *= sWorld.getRate(RATE_HONOR); + honor *= (GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN) + 100.0f)/100.0f; if(groupsize > 1) honor /= groupsize; @@ -13897,6 +13898,33 @@ void Player::SendCanTakeQuestResponse( uint32 msg ) sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID"); } +void Player::SendQuestConfirmAccept(const Quest* pQuest, Player* pReceiver) +{ + if (pReceiver) + { + std::string strTitle = pQuest->GetTitle(); + + int loc_idx = pReceiver->GetSession()->GetSessionDbLocaleIndex(); + + if (loc_idx >= 0) + { + if (const QuestLocale* pLocale = objmgr.GetQuestLocale(pQuest->GetQuestId())) + { + if (pLocale->Title.size() > loc_idx && !pLocale->Title[loc_idx].empty()) + strTitle = pLocale->Title[loc_idx]; + } + } + + WorldPacket data(SMSG_QUEST_CONFIRM_ACCEPT, (4 + strTitle.size() + 8)); + data << uint32(pQuest->GetQuestId()); + data << strTitle; + data << uint64(GetGUID()); + pReceiver->GetSession()->SendPacket(&data); + + sLog.outDebug("WORLD: Sent SMSG_QUEST_CONFIRM_ACCEPT"); + } +} + void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg ) { if( pPlayer ) @@ -16536,9 +16564,13 @@ void Player::Whisper(const std::string& text, uint32 language,uint64 receiver) BuildPlayerChat(&data, CHAT_MSG_WHISPER, text, language); rPlayer->GetSession()->SendPacket(&data); - data.Initialize(SMSG_MESSAGECHAT, 200); - rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, text, language); - GetSession()->SendPacket(&data); + // not send confirmation for addon messages + if (language != LANG_ADDON) + { + data.Initialize(SMSG_MESSAGECHAT, 200); + rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, text, language); + GetSession()->SendPacket(&data); + } } else { @@ -18789,7 +18821,7 @@ void Player::UpdateForQuestWorldObjects() { if(IS_GAMEOBJECT_GUID(*itr)) { - GameObject *obj = HashMapHolder::Find(*itr); + GameObject *obj = GetMap()->GetGameObject(*itr); if(obj) obj->BuildValuesUpdateBlockForPlayer(&udata,this); } diff --git a/src/game/Player.h b/src/game/Player.h index b2efe78c7..21e59a85a 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1369,6 +1369,7 @@ class MANGOS_DLL_SPEC Player : public Unit void SendQuestFailed( uint32 quest_id ); void SendQuestTimerFailed( uint32 quest_id ); void SendCanTakeQuestResponse( uint32 msg ); + void SendQuestConfirmAccept(Quest const* pQuest, Player* pReceiver); void SendPushToPartyResponse( Player *pPlayer, uint32 msg ); void SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count ); void SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, uint32 creatureOrGO_idx, uint32 old_count, uint32 add_count ); diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h index 999e8de7a..02729db1d 100644 --- a/src/game/QuestDef.h +++ b/src/game/QuestDef.h @@ -120,7 +120,7 @@ enum __QuestFlags { // Flags used at server and sent to client QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently - QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT + QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT QUEST_FLAGS_EXPLORATION = 0x00000004, // Not used currently QUEST_FLAGS_SHARABLE = 0x00000008, // Can be shared: Player::CanShareQuest() //QUEST_FLAGS_NONE2 = 0x00000010, // Not used currently diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 1cef7dd22..5f105b411 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -154,6 +154,30 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) { _player->AddQuest( qInfo, pObject ); + if (qInfo->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) + { + if (Group* pGroup = _player->GetGroup()) + { + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* pPlayer = itr->getSource(); + + if (!pPlayer || pPlayer == _player) // not self + continue; + + if (pPlayer->CanTakeQuest(qInfo, true)) + { + pPlayer->SetDivider(_player->GetGUID()); + + //need confirmation that any gossip window will close + pPlayer->PlayerTalkClass->CloseGossip(); + + _player->SendQuestConfirmAccept(qInfo, pPlayer); + } + } + } + } + if ( _player->CanCompleteQuest( quest ) ) _player->CompleteQuest( quest ); @@ -370,7 +394,34 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recv_data) uint32 quest; recv_data >> quest; - sLog.outDebug( "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u",quest ); + sLog.outDebug("WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u", quest); + + if (const Quest* pQuest = objmgr.GetQuestTemplate(quest)) + { + if (!pQuest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) + return; + + Player* pOriginalPlayer = ObjectAccessor::FindPlayer(_player->GetDivider()); + + if (!pOriginalPlayer) + return; + + if (pQuest->GetType() == QUEST_TYPE_RAID) + { + if (!_player->IsInSameRaidWith(pOriginalPlayer)) + return; + } + else + { + if (!_player->IsInSameGroupWith(pOriginalPlayer)) + return; + } + + if (_player->CanAddQuest(pQuest, true)) + _player->AddQuest(pQuest, NULL); // NULL, this prevent DB script from duplicate running + + _player->SetDivider(0); + } } void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 4acc06d20..37c38c742 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -956,18 +956,31 @@ enum Mechanics // Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6) #define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \ - (1<EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY) + if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY) school_immune |= uint32(m_spellInfo->EffectMiscValue[i]); - else if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY) - mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i]); - else if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DISPEL_IMMUNITY) + else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY) + mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i]-1); + else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY_MASK) + mechanic_immune |= uint32(m_spellInfo->EffectMiscValue[i]); + else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DISPEL_IMMUNITY) dispel_immune |= GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[i])); } // immune movement impairment and loss of control - if(m_spellInfo->Id == 42292) + if (m_spellInfo->Id == 42292) mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK; } @@ -4889,33 +4891,33 @@ SpellCastResult Spell::CheckCasterAuras() const SpellCastResult prevented_reason = SPELL_CAST_OK; // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out uint32 unitflag = m_caster->GetUInt32Value(UNIT_FIELD_FLAGS); // Get unit state - if(unitflag & UNIT_FLAG_STUNNED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)) + if (unitflag & UNIT_FLAG_STUNNED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)) prevented_reason = SPELL_FAILED_STUNNED; - else if(unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED)) + else if (unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED)) prevented_reason = SPELL_FAILED_CONFUSED; - else if(unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) + else if (unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) prevented_reason = SPELL_FAILED_FLEEING; - else if(unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) + else if (unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) prevented_reason = SPELL_FAILED_SILENCED; - else if(unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) + else if (unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) prevented_reason = SPELL_FAILED_PACIFIED; // Attr must make flag drop spell totally immune from all effects - if(prevented_reason != SPELL_CAST_OK) + if (prevented_reason != SPELL_CAST_OK) { - if(school_immune || mechanic_immune || dispel_immune) + if (school_immune || mechanic_immune || dispel_immune) { //Checking auras is needed now, because you are prevented by some state but the spell grants immunity. Unit::AuraMap const& auras = m_caster->GetAuras(); for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if(itr->second) + if (itr->second) { - if( GetSpellMechanicMask(itr->second->GetSpellProto(), itr->second->GetEffIndex()) & mechanic_immune ) + if (GetSpellMechanicMask(itr->second->GetSpellProto(), itr->second->GetEffIndex()) & mechanic_immune) continue; - if( GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune ) + if (GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune) continue; - if( (1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune) + if ((1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune) continue; // Make a second check for spell failed so the right SPELL_FAILED message is returned. diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 10b4fd3e5..2700d1d2f 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -189,7 +189,7 @@ enum AuraType SPELL_AURA_SAFE_FALL = 144, SPELL_AURA_MOD_PET_TALENT_POINTS = 145, SPELL_AURA_ALLOW_TAME_PET_TYPE = 146, - SPELL_AURA_ADD_CREATURE_IMMUNITY = 147, + SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147, SPELL_AURA_RETAIN_COMBO_POINTS = 148, SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index ec29a8e0e..43f9e5a5c 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -197,7 +197,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraSafeFall, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes &Aura::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS &Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE - &Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY + &Aura::HandleModMechanicImmunityMask, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY implemented in Unit::IsImmunedToSpell and Unit::IsImmunedToSpellEffect (check part) &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT @@ -331,7 +331,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNULL, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon &Aura::HandleNULL, //279 visual effects? 58836 and 57507 &Aura::HandleModTargetArmorPct, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT - &Aura::HandleNULL, //281 SPELL_AURA_MOD_HONOR_GAIN + &Aura::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN implemented in Player::RewardHonor &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT &Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus &Aura::HandleUnused, //284 51 spells @@ -2887,7 +2887,8 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real) // If spell that caused this aura has Croud Control or Daze effect if((aurMechMask & MECHANIC_NOT_REMOVED_BY_SHAPESHIFT) || // some Daze spells have these parameters instead of MECHANIC_DAZE (skip snare spells) - aurSpellInfo->SpellIconID == 15 && aurSpellInfo->Dispel == 0 && (aurMechMask & (1 << MECHANIC_SNARE))==0) + aurSpellInfo->SpellIconID == 15 && aurSpellInfo->Dispel == 0 && + (aurMechMask & (1 << (MECHANIC_SNARE-1)))==0) { ++iter; continue; @@ -4171,32 +4172,13 @@ void Aura::HandleModMechanicImmunity(bool apply, bool /*Real*/) if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) { - uint32 mechanic = 1 << misc; + uint32 mechanic = 1 << (misc-1); //immune movement impairment and loss of control if(GetId()==42292 || GetId()==59752) mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK; - Unit::AuraMap& Auras = m_target->GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) - { - next = iter; - ++next; - SpellEntry const *spell = iter->second->GetSpellProto(); - if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) && // spells unaffected by invulnerability - spell->Id != GetId()) - { - //check for mechanic mask - if(GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic) - { - m_target->RemoveAurasDueToSpell(spell->Id); - if(Auras.empty()) - break; - else - next = Auras.begin(); - } - } - } + m_target->RemoveAurasAtMechanicImmunity(mechanic,GetId()); } m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,misc,apply); @@ -4224,6 +4206,16 @@ void Aura::HandleModMechanicImmunity(bool apply, bool /*Real*/) } } +void Aura::HandleModMechanicImmunityMask(bool apply, bool /*Real*/) +{ + uint32 mechanic = m_modifier.m_miscvalue; + + if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) + m_target->RemoveAurasAtMechanicImmunity(mechanic,GetId()); + + // check implemented in Unit::IsImmunedToSpell and Unit::IsImmunedToSpellEffect +} + //this method is called whenever we add / remove aura which gives m_target some imunity to some spell effect void Aura::HandleAuraModEffectImmunity(bool apply, bool /*Real*/) { diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 397338227..0695271e7 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -159,6 +159,7 @@ class MANGOS_DLL_SPEC Aura void HandleFarSight(bool Apply, bool Real); void HandleModPossessPet(bool Apply, bool Real); void HandleModMechanicImmunity(bool Apply, bool Real); + void HandleModMechanicImmunityMask(bool Apply, bool Real); void HandleAuraModSkill(bool Apply, bool Real); void HandleModDamagePercentDone(bool Apply, bool Real); void HandleModPercentStat(bool Apply, bool Real); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 96b1e6252..db09186e1 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4989,26 +4989,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) if(!unitTarget) return; // Removes snares and roots. - uint32 mechanic_mask = (1<GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) - { - next = iter; - ++next; - Aura *aur = iter->second; - if (!aur->IsPositive()) //only remove negative spells - { - // check for mechanic mask - if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask) - { - unitTarget->RemoveAurasDueToSpell(aur->GetId()); - if(Auras.empty()) - break; - else - next = Auras.begin(); - } - } - } + unitTarget->RemoveAurasAtMechanicImmunity(IMMUNE_TO_ROOT_AND_SNARE_MASK,30918,true); break; } // Flame Crash diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index a91ca0302..8df296ca2 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1633,6 +1633,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons // Beacon of Light and Light's Beacon if ((spellInfo_1->SpellIconID == 3032) && (spellInfo_2->SpellIconID == 3032)) return false; + + // Concentration Aura and Improved Concentration Aura and Aura Mastery + if ((spellInfo_1->SpellIconID == 1487) && (spellInfo_2->SpellIconID == 1487)) + return false; } // Combustion and Fire Protection Aura (multi-family check) @@ -3309,23 +3313,33 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto // Get by mechanic uint32 mechanic = GetAllSpellMechanicMask(spellproto); - if (mechanic == MECHANIC_NONE) return DIMINISHING_NONE; - if (mechanic & ((1<Mechanic) - mask |= 1<Mechanic; + mask |= 1 << (spellInfo->Mechanic - 1); if (spellInfo->EffectMechanic[effect]) - mask |= 1<EffectMechanic[effect]; + mask |= 1 << (spellInfo->EffectMechanic[effect] - 1); return mask; } @@ -398,10 +398,10 @@ inline uint32 GetAllSpellMechanicMask(SpellEntry const* spellInfo) { uint32 mask = 0; if (spellInfo->Mechanic) - mask |= 1<Mechanic; + mask |= 1 << (spellInfo->Mechanic - 1); for (int i=0; i< 3; ++i) if (spellInfo->EffectMechanic[i]) - mask |= 1<EffectMechanic[i]; + mask |= 1 << (spellInfo->EffectMechanic[i]-1); return mask; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 23c0cac95..b28159b2b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4078,10 +4078,13 @@ void Unit::RemoveArenaAuras(bool onleave) // used to remove positive visible auras in arenas for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();) { - if ( !(iter->second->GetSpellProto()->AttributesEx4 & (1<<21)) // don't remove stances, shadowform, pally/hunter auras - && !iter->second->IsPassive() // don't remove passive auras - && (!(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) || !(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNK8)) // not unaffected by invulnerability auras or not having that unknown flag (that seemed the most probable) - && (iter->second->IsPositive() != onleave)) // remove positive buffs on enter, negative buffs on leave + if (!(iter->second->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_UNK21) && + // don't remove stances, shadowform, pally/hunter auras + !iter->second->IsPassive() && // don't remove passive auras + (!(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) || + !(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNK8)) && + // not unaffected by invulnerability auras or not having that unknown flag (that seemed the most probable) + (iter->second->IsPositive() != onleave)) // remove positive buffs on enter, negative buffs on leave RemoveAura(iter); else ++iter; @@ -5191,7 +5194,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) return false; // Need stun or root mechanic - if (!(GetAllSpellMechanicMask(procSpell) & ((1<Id) @@ -6355,7 +6358,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) return false; // Need snare or root mechanic - if (!(GetAllSpellMechanicMask(procSpell) & ((1<GetAurasByType(SPELL_AURA_MOD_HEALING); for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i) - if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0) + if ((*i)->GetModifier()->m_miscvalue & schoolMask) AdvertisedBenefit += (*i)->GetModifier()->m_amount; + return AdvertisedBenefit; } @@ -8974,13 +8978,13 @@ bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask) //If m_immuneToSchool type contain this school type, IMMUNE damage. SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr) - if(itr->type & shoolMask) + if (itr->type & shoolMask) return true; //If m_immuneToDamage type contain magic, IMMUNE damage. SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE]; for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr) - if(itr->type & shoolMask) + if (itr->type & shoolMask) return true; return false; @@ -8996,26 +9000,30 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo) SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL]; for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr) - if(itr->type == spellInfo->Dispel) + if (itr->type == spellInfo->Dispel) return true; - if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity + if (!(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity !(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it) { SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr) - if( !(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) && - (itr->type & GetSpellSchoolMask(spellInfo)) ) + if (!(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) && + (itr->type & GetSpellSchoolMask(spellInfo))) return true; } - SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; - for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) + if(uint32 mechanic = spellInfo->Mechanic) { - if(itr->type == spellInfo->Mechanic) - { - return true; - } + SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; + for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) + if (itr->type == mechanic) + return true; + + AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MECHANIC_IMMUNITY_MASK); + for(AuraList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter) + if ((*iter)->GetModifier()->m_miscvalue & (1 << (mechanic-1))) + return true; } return false; @@ -9027,14 +9035,19 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con uint32 effect = spellInfo->Effect[index]; SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT]; for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr) - if(itr->type == effect) + if (itr->type == effect) return true; if(uint32 mechanic = spellInfo->EffectMechanic[index]) { SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) - if(itr->type == mechanic) + if (itr->type == mechanic) + return true; + + AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MECHANIC_IMMUNITY_MASK); + for(AuraList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter) + if ((*iter)->GetModifier()->m_miscvalue & (1 << (mechanic-1))) return true; } @@ -9042,8 +9055,9 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con { SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE]; for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr) - if(itr->type == aura) + if (itr->type == aura) return true; + // Check for immune to application of harmful magical effects AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL); for(AuraList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter) @@ -9058,13 +9072,13 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con bool Unit::IsDamageToThreatSpell(SpellEntry const * spellInfo) const { - if(!spellInfo) + if (!spellInfo) return false; uint32 family = spellInfo->SpellFamilyName; uint64 flags = spellInfo->SpellFamilyFlags; - if((family == 5 && flags == 256) || //Searing Pain + if ((family == 5 && flags == 256) || //Searing Pain (family == 6 && flags == 8192) || //Mind Blast (family == 11 && flags == 1048576)) //Earth Shock return true; @@ -9074,10 +9088,10 @@ bool Unit::IsDamageToThreatSpell(SpellEntry const * spellInfo) const uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType attType, SpellEntry const *spellProto, DamageEffectType damagetype, uint32 stack) { - if(!pVictim) + if (!pVictim) return pdamage; - if(pdamage == 0) + if (pdamage == 0) return pdamage; // differentiate for weapon damage based spells @@ -9089,7 +9103,7 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att // Shred also have bonus as MECHANIC_BLEED damages if (spellProto && spellProto->SpellFamilyName==SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags & UI64LIT(0x00008000)) - mechanicMask |= (1 << MECHANIC_BLEED); + mechanicMask |= (1 << (MECHANIC_BLEED-1)); // FLAT damage bonus auras @@ -11722,7 +11736,7 @@ void Unit::SetFeared(bool apply, uint64 const& casterGUID, uint32 spellID, uint3 GetMotionMaster()->Initialize(); // attack caster if can - Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL); + Unit* caster = Unit::GetUnit(*this, casterGUID); if(caster && ((Creature*)this)->AI()) ((Creature*)this)->AI()->AttackedBy(caster); } @@ -12416,6 +12430,31 @@ void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) } } +void Unit::RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive /*= false*/) +{ + Unit::AuraMap& auras = GetAuras(); + for(Unit::AuraMap::iterator iter = auras.begin(); iter != auras.end();) + { + SpellEntry const *spell = iter->second->GetSpellProto(); + if (spell->Id == exceptSpellId) + ++iter; + else if (non_positive && iter->second->IsPositive()) + ++iter; + else if (spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) + ++iter; + else if (GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechMask) + { + RemoveAurasDueToSpell(spell->Id); + if(auras.empty()) + break; + else + iter = auras.begin(); + } + else + ++iter; + } +} + void Unit::SetPhaseMask(uint32 newPhaseMask, bool update) { if(newPhaseMask==GetPhaseMask()) diff --git a/src/game/Unit.h b/src/game/Unit.h index 72017fc1b..b1787d6f7 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1214,6 +1214,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void RemoveAurasDueToSpellByCancel(uint32 spellId); void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo); void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0); + void RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive = false); void RemoveSpellsCausingAura(AuraType auraType); void RemoveRankAurasDueToSpell(uint32 spellId); diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp index 5c5fad437..d856d3657 100644 --- a/src/game/Vehicle.cpp +++ b/src/game/Vehicle.cpp @@ -31,21 +31,23 @@ Vehicle::Vehicle() : Creature(), m_vehicleId(0) Vehicle::~Vehicle() { - if(m_uint32Values) // only for fully created Object - ObjectAccessor::Instance().RemoveObject(this); } void Vehicle::AddToWorld() { ///- Register the vehicle for guid lookup - if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + if(!IsInWorld()) + GetMap()->GetObjectsStore().insert(GetGUID(), (Vehicle*)this); + Unit::AddToWorld(); } void Vehicle::RemoveFromWorld() { ///- Remove the vehicle from the accessor - if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + if(IsInWorld()) + GetMap()->GetObjectsStore().erase(GetGUID(), (Vehicle*)NULL); + ///- Don't call the function for Creature, normal mobs + totems go in a different storage Unit::RemoveFromWorld(); } diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp index 1212d94fa..68113ee7d 100644 --- a/src/mangosd/Master.cpp +++ b/src/mangosd/Master.cpp @@ -398,8 +398,8 @@ int Master::Run() bool Master::_StartDB() { ///- Get world database info from configuration file - std::string dbstring; - if(!sConfig.GetString("WorldDatabaseInfo", &dbstring)) + std::string dbstring = sConfig.GetStringDefault("WorldDatabaseInfo", ""); + if(dbstring.empty()) { sLog.outError("Database not specified in configuration file"); return false; @@ -416,7 +416,8 @@ bool Master::_StartDB() if(!WorldDatabase.CheckRequiredField("db_version",REVISION_DB_MANGOS)) return false; - if(!sConfig.GetString("CharacterDatabaseInfo", &dbstring)) + dbstring = sConfig.GetStringDefault("CharacterDatabaseInfo", ""); + if(dbstring.empty()) { sLog.outError("Character Database not specified in configuration file"); return false; @@ -434,7 +435,8 @@ bool Master::_StartDB() return false; ///- Get login database info from configuration file - if(!sConfig.GetString("LoginDatabaseInfo", &dbstring)) + dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", ""); + if(dbstring.empty()) { sLog.outError("Login database not specified in configuration file"); return false; diff --git a/src/realmd/Main.cpp b/src/realmd/Main.cpp index 4e53ed7ab..13fdc5747 100644 --- a/src/realmd/Main.cpp +++ b/src/realmd/Main.cpp @@ -50,7 +50,7 @@ char serviceDescription[] = "Massive Network Game Object Server"; int m_ServiceStatus = -1; #endif -bool StartDB(std::string &dbstring); +bool StartDB(); void UnhookSignals(); void HookSignals(); @@ -187,8 +187,7 @@ extern int main(int argc, char **argv) } ///- Initialize the database connection - std::string dbstring; - if(!StartDB(dbstring)) + if(!StartDB()) return 1; ///- Get the list of realms for the server @@ -312,9 +311,10 @@ void OnSignal(int s) } /// Initialize connection to the database -bool StartDB(std::string &dbstring) +bool StartDB() { - if(!sConfig.GetString("LoginDatabaseInfo", &dbstring)) + std::string dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", ""); + if(dbstring.empty()) { sLog.outError("Database not specified"); return false; diff --git a/src/shared/Common.h b/src/shared/Common.h index b6b795e16..1b46bf8c5 100644 --- a/src/shared/Common.h +++ b/src/shared/Common.h @@ -81,12 +81,6 @@ #include #include -#if PLATFORM == PLATFORM_WINDOWS -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp -#endif - #include #include #include @@ -103,7 +97,6 @@ #include #include - #if PLATFORM == PLATFORM_WINDOWS # define FD_SETSIZE 4096 # include @@ -128,9 +121,7 @@ #define I32FMT "%08I32X" #define I64FMT "%016I64X" #define snprintf _snprintf -#define atoll __atoi64 #define vsnprintf _vsnprintf -#define strdup _strdup #define finite(X) _finite(X) #else diff --git a/src/shared/Config/Config.cpp b/src/shared/Config/Config.cpp index 1d27c7775..6efcb6968 100644 --- a/src/shared/Config/Config.cpp +++ b/src/shared/Config/Config.cpp @@ -21,17 +21,16 @@ INSTANTIATE_SINGLETON_1(Config); -Config::Config() : mIgnoreCase(true), mConf(NULL) +Config::Config() +: mIgnoreCase(true), mConf(NULL) { } - Config::~Config() { delete mConf; } - bool Config::SetSource(const char *file, bool ignorecase) { mIgnoreCase = ignorecase; @@ -46,7 +45,7 @@ bool Config::Reload() mConf = new DOTCONFDocument(mIgnoreCase ? DOTCONFDocument::CASEINSENSETIVE : - DOTCONFDocument::CASESENSETIVE); + DOTCONFDocument::CASESENSITIVE); if (mConf->setContent(mFilename.c_str()) == -1) { @@ -58,117 +57,58 @@ bool Config::Reload() return true; } -bool Config::GetString(const char* name, std::string *value) -{ - if(!mConf) - return false; - - DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; - - *value = node->getValue(); - - return true; -} - -bool Config::GetString(const char* name, char const **value) -{ - if(!mConf) - return false; - - DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; - - *value = node->getValue(); - - return true; -} - - std::string Config::GetStringDefault(const char* name, const char* def) { - if(!mConf) + if (!mConf) return std::string(def); DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) + if (!node || !node->getValue()) return std::string(def); return std::string(node->getValue()); } - -bool Config::GetBool(const char* name, bool *value) +bool Config::GetBoolDefault(const char* name, bool def) { - if(!mConf) - return false; + if (!mConf) + return def; DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; + if (!node || !node->getValue()) + return def; const char* str = node->getValue(); - if(strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 || + if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 || strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 || strcmp(str, "1") == 0) - { - *value = true; - } + return true; else - *value = false; - - return true; -} - - -bool Config::GetBoolDefault(const char* name, const bool def) -{ - bool val; - return GetBool(name, &val) ? val : def; -} - - -bool Config::GetInt(const char* name, int *value) -{ - if(!mConf) return false; +} + + +int32 Config::GetIntDefault(const char* name, int32 def) +{ + if (!mConf) + return def; DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; + if (!node || !node->getValue()) + return def; - *value = atoi(node->getValue()); - - return true; + return atoi(node->getValue()); } -bool Config::GetFloat(const char* name, float *value) +float Config::GetFloatDefault(const char* name, float def) { - if(!mConf) - return false; + if (!mConf) + return def; DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; + if (!node || !node->getValue()) + return def; - *value = atof(node->getValue()); - - return true; -} - - -int Config::GetIntDefault(const char* name, const int def) -{ - int val; - return GetInt(name, &val) ? val : def; -} - - -float Config::GetFloatDefault(const char* name, const float def) -{ - float val; - return (GetFloat(name, &val) ? val : def); + return atof(node->getValue()); } diff --git a/src/shared/Config/Config.h b/src/shared/Config/Config.h index e09dffe38..989c8e19f 100644 --- a/src/shared/Config/Config.h +++ b/src/shared/Config/Config.h @@ -27,27 +27,22 @@ class DOTCONFDocument; class MANGOS_DLL_SPEC Config { public: + Config(); ~Config(); bool SetSource(const char *file, bool ignorecase = true); bool Reload(); - bool GetString(const char* name, std::string *value); - bool GetString(const char* name, char const **value); std::string GetStringDefault(const char* name, const char* def); - - bool GetBool(const char* name, bool *value); bool GetBoolDefault(const char* name, const bool def = false); - - bool GetInt(const char* name, int *value); - int GetIntDefault(const char* name, const int def); - - bool GetFloat(const char* name, float *value); + int32 GetIntDefault(const char* name, const int32 def); float GetFloatDefault(const char* name, const float def); std::string GetFilename() const { return mFilename; } + private: + std::string mFilename; bool mIgnoreCase; DOTCONFDocument *mConf; diff --git a/src/shared/Config/dotconfpp/dotconfpp.cpp b/src/shared/Config/dotconfpp/dotconfpp.cpp index d6fbc4ea8..24872d5cb 100644 --- a/src/shared/Config/dotconfpp/dotconfpp.cpp +++ b/src/shared/Config/dotconfpp/dotconfpp.cpp @@ -1,64 +1,68 @@ - #include "Common.h" - #include "dotconfpp.h" #ifdef WIN32 -#define PATH_MAX _MAX_PATH -#define strcasecmp stricmp -#define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH) -#include +# define PATH_MAX _MAX_PATH +# define strcasecmp stricmp +# define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH) +# include #else -#include -#include -#include -#include +# include +# include +# include +# include #endif #if !defined(R_OK) -#define R_OK 04 +# define R_OK 04 #endif -DOTCONFDocumentNode::DOTCONFDocumentNode():previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL), - values(NULL), valuesCount(0), - name(NULL), lineNum(0), fileName(NULL), closed(true) +DOTCONFDocumentNode::DOTCONFDocumentNode() +: previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL), +values(NULL), valuesCount(0), name(NULL), lineNum(0), +fileName(NULL), closed(true) { } DOTCONFDocumentNode::~DOTCONFDocumentNode() { free(name); - if(values != NULL){ - for(int i = 0 ; i < valuesCount; i++){ + + if (values != NULL) + { + for (int i = 0; i < valuesCount; ++i) free(values[i]); - } + free(values); } } -void DOTCONFDocumentNode::pushValue(char * _value) +void DOTCONFDocumentNode::pushValue(char* _value) { ++valuesCount; - values = (char**)realloc(values, valuesCount*sizeof(char*)); - values[valuesCount-1] = strdup(_value); + values = (char**)realloc(values, valuesCount * sizeof(char*)); + values[valuesCount - 1] = strdup(_value); } const char* DOTCONFDocumentNode::getValue(int index) const { - if(index >= valuesCount){ + if (index >= valuesCount) return NULL; - } + return values[index]; } -DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity): - mempool(NULL), - curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL) +DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity) +: mempool(NULL), curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL) { - if(caseSensitivity == CASESENSETIVE){ - cmp_func = strcmp; - } else { - cmp_func = strcasecmp; + switch (caseSensitivity) + { + case CASESENSITIVE: + cmp_func = strcmp; + break; + case CASEINSENSETIVE: + cmp_func = strcasecmp; + break; } mempool = new AsyncDNSMemPool(1024); @@ -67,195 +71,247 @@ DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity) DOTCONFDocument::~DOTCONFDocument() { - for(std::list::iterator i = nodeTree.begin(); i != nodeTree.end(); i++){ + for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i) delete(*i); - } - for(std::list::iterator i = requiredOptions.begin(); i != requiredOptions.end(); i++){ + + for (CharList::iterator i = requiredOptions.begin(); i != requiredOptions.end(); ++i) free(*i); - } - for(std::list::iterator i = processedFiles.begin(); i != processedFiles.end(); i++){ + + for (CharList::iterator i = processedFiles.begin(); i != processedFiles.end(); ++i) free(*i); - } + free(fileName); delete mempool; } -int DOTCONFDocument::cleanupLine(char * line) +int DOTCONFDocument::cleanupLine(char* line) { - char * start = line; - char * bg = line; + char* start = line; + char* bg = line; bool multiline = false; bool concat = false; - char * word = NULL; + char* word = NULL; - if(!words.empty() && quoted) + if (!words.empty() && quoted) concat = true; - while(*line){ - if((*line == '#' || *line == ';') && !quoted){ + while (*line) + { + if ((*line == '#' || *line == ';') && !quoted) + { *bg = 0; - if(strlen(start)){ - - if(concat){ - word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); + if (strlen(start)) + { + if (concat) + { + word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1); strcpy(word, words.back()); strcat(word, start); words.pop_back(); concat = false; - } else { - word = mempool->strdup(start); } + else + word = mempool->Strdup(start); + words.push_back(word); } + break; } - if(*line == '=' && !quoted){ - *line = ' ';continue; + + if (*line == '=' && !quoted) + { + *line = ' '; + continue; } // Allowing \" in there causes problems with directory paths // like "C:\MaNGOS\" //if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){ - if(*line == '\\' && (*(line+1) == '\'')) { - *bg++ = *(line+1); - line+=2; continue; + if (*line == '\\' && (*(line + 1) == '\'')) + { + *bg++ = *(line + 1); + line += 2; + continue; } - if(*line == '\\' && *(line+1) == 'n'){ - *bg++ = '\n'; - line+=2; continue; - } - if(*line == '\\' && *(line+1) == 'r'){ - *bg++ = '\r'; - line+=2; continue; - } - if(*line == '\\' && (*(line+1) == '\n' || *(line+1) == '\r')){ - *bg = 0; - if(strlen(start)){ - if(concat){ - word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); + if (*line == '\\' && *(line + 1) == 'n') + { + *bg++ = '\n'; + line += 2; + continue; + } + + if (*line == '\\' && *(line + 1) == 'r') + { + *bg++ = '\r'; + line += 2; + continue; + } + + if (*line == '\\' && (*(line + 1) == '\n' || *(line + 1) == '\r')) + { + *bg = 0; + if (strlen(start)) + { + if (concat) + { + word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1); strcpy(word, words.back()); strcat(word, start); words.pop_back(); concat = false; - } else { - word = mempool->strdup(start); } + else + word = mempool->Strdup(start); + words.push_back(word); } + multiline = true; break; } - if(*line == '"' || *line == '\''){ - quoted = !quoted; - ++line; continue; - } - if(isspace((unsigned char)*line) && !quoted){ - *bg++ = 0; - if(strlen(start)){ - if(concat){ - word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); + if (*line == '"' || *line == '\'') + { + quoted = !quoted; + ++line; + continue; + } + + if (isspace((unsigned char)*line) && !quoted) + { + *bg++ = 0; + if (strlen(start)) + { + if (concat) + { + word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1); strcpy(word, words.back()); strcat(word, start); words.pop_back(); concat = false; - } else { - word = mempool->strdup(start); } + else + word = mempool->Strdup(start); + words.push_back(word); } + start = bg; - while(isspace((unsigned char)*++line)) {} + while (isspace((unsigned char)*++line)) + { + } continue; } + *bg++ = *line++; } - if(quoted && !multiline){ + if (quoted && !multiline) + { error(curLine, fileName, "unterminated quote"); return -1; } - return multiline?1:0; + return multiline ? 1 : 0; } int DOTCONFDocument::parseLine() { - char * word = NULL; - char * nodeName = NULL; - char * nodeValue = NULL; - DOTCONFDocumentNode * tagNode = NULL; + char* word = NULL; + char* nodeName = NULL; + char* nodeValue = NULL; + DOTCONFDocumentNode* tagNode = NULL; bool newNode = false; - for(std::list::iterator i = words.begin(); i != words.end(); i++) { + for (CharList::iterator i = words.begin(); i != words.end(); ++i) + { word = *i; - if(*word == '<'){ + if (*word == '<') newNode = true; - } - if(newNode){ + if (newNode) + { nodeValue = NULL; nodeName = NULL; newNode = false; } size_t wordLen = strlen(word); - if(word[wordLen-1] == '>'){ - word[wordLen-1] = 0; + if (word[wordLen - 1] == '>') + { + word[wordLen - 1] = 0; newNode = true; } - if(nodeName == NULL){ + if (nodeName == NULL) + { nodeName = word; bool closed = true; - if(*nodeName == '<'){ - if(*(nodeName+1) != '/'){ + if (*nodeName == '<') + { + if (*(nodeName + 1) != '/') + { ++nodeName; closed = false; - } else { - nodeName+=2; - std::list::reverse_iterator itr=nodeTree.rbegin(); - for(; itr!=nodeTree.rend(); ++itr){ - if(!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed){ + } + else + { + NodeList::reverse_iterator itr = nodeTree.rbegin(); + nodeName += 2; + for (; itr != nodeTree.rend(); ++itr) + { + if (!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed) + { (*itr)->closed = true; curParent = (*itr)->parentNode; curPrev = *itr; break; } } - if(itr==nodeTree.rend()){ + + if(itr == nodeTree.rend()) + { error(curLine, fileName, "not matched closing tag ", nodeName); return -1; } + continue; } } + tagNode = new DOTCONFDocumentNode; tagNode->name = strdup(nodeName); tagNode->document = this; tagNode->fileName = processedFiles.back(); tagNode->lineNum = curLine; tagNode->closed = closed; - if(!nodeTree.empty()){ - DOTCONFDocumentNode * prev = nodeTree.back(); - if(prev->closed){ + if(!nodeTree.empty()) + { + DOTCONFDocumentNode* prev = nodeTree.back(); + if (prev->closed) + { curPrev->nextNode = tagNode; tagNode->previousNode = curPrev; tagNode->parentNode = curParent; - - } else { + } + else + { prev->childNode = tagNode; tagNode->parentNode = prev; curParent = prev; } } + nodeTree.push_back(tagNode); curPrev = tagNode; - } else { + } + else + { nodeValue = word; tagNode->pushValue(nodeValue); } @@ -263,7 +319,8 @@ int DOTCONFDocument::parseLine() return 0; } -int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent) + +int DOTCONFDocument::parseFile(DOTCONFDocumentNode* _parent) { char str[512]; int ret = 0; @@ -273,27 +330,32 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent) quoted = false; size_t slen = 0; - while(fgets(str, 511, file)){ + while (fgets(str, 511, file)) + { ++curLine; - slen = strlen(str); - if( slen >= 510 ){ + slen = strlen(str); + if (slen >= 510) error(curLine, fileName, "warning: line too long"); + + if (str[slen - 1] != '\n') + { + str[slen] = '\n'; + str[slen + 1] = 0; } - if(str[slen-1] != '\n'){ - str[slen] = '\n'; - str[slen+1] = 0; - } - if((ret = cleanupLine(str)) == -1){ + + if ((ret = cleanupLine(str)) == -1) break; - } - if(ret == 0){ - if(!words.empty()){ + + if (ret == 0) + { + if (!words.empty()) + { ret = parseLine(); - mempool->free(); + mempool->Free(); words.clear(); - if(ret == -1){ + + if(ret == -1) break; - } } } } @@ -301,46 +363,51 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent) return ret; } -int DOTCONFDocument::checkConfig(const std::list::iterator & from) +int DOTCONFDocument::checkConfig(const NodeList::iterator& from) { int ret = 0; - DOTCONFDocumentNode * tagNode = NULL; + DOTCONFDocumentNode* tagNode = NULL; int vi = 0; - for(std::list::iterator i = from; i != nodeTree.end(); i++){ + for (NodeList::iterator i = from; i != nodeTree.end(); ++i) + { tagNode = *i; - if(!tagNode->closed){ + if (!tagNode->closed) + { error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name); ret = -1; break; } - vi = 0; - while( vi < tagNode->valuesCount ){ - if(strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}') ){ - ret = macroSubstitute(tagNode, vi ); - mempool->free(); - if(ret == -1){ + vi = 0; + while (vi < tagNode->valuesCount) + { + if (strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}')) + { + ret = macroSubstitute(tagNode, vi); + mempool->Free(); + if (ret == -1) break; - } } + ++vi; } - if(ret == -1){ + + if (ret == -1) break; - } } return ret; } -int DOTCONFDocument::setContent(const char * _fileName) +int DOTCONFDocument::setContent(const char* _fileName) { int ret = 0; char realpathBuf[PATH_MAX]; - if(realpath(_fileName, realpathBuf) == NULL){ - error(0, NULL, "realpath(%s) failed: %s", _fileName, strerror(errno)); + if (realpath(_fileName, realpathBuf) == NULL) + { + error(0, NULL, "realpath (%s) failed: %s", _fileName, strerror(errno)); return -1; } @@ -348,79 +415,90 @@ int DOTCONFDocument::setContent(const char * _fileName) processedFiles.push_back(strdup(realpathBuf)); - if(( file = fopen(fileName, "r")) == NULL){ + if ((file = fopen(fileName, "r")) == NULL) + { error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno)); return -1; } + // Try read utf8 header and skip it if exist - uint32 utf8header = 0; + unsigned int utf8header = 0; fgets((char*)&utf8header, 4, file); // Try read header - if (utf8header!=0x00BFBBEF) // If not exist + if (utf8header != 0x00BFBBEF) // If not exist fseek(file, 0, SEEK_SET); // Reset read position ret = parseFile(); - (void) fclose(file); + fclose(file); - if(!ret){ - - if( (ret = checkConfig(nodeTree.begin())) == -1){ + if (!ret) + { + if ((ret = checkConfig(nodeTree.begin())) == -1) return -1; - } - std::list::iterator from; - DOTCONFDocumentNode * tagNode = NULL; + NodeList::iterator from; + DOTCONFDocumentNode* tagNode = NULL; int vi = 0; - for(std::list::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){ + for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i) + { tagNode = *i; - if(!cmp_func("DOTCONFPPIncludeFile", tagNode->name)){ + if (!cmp_func("DOTCONFPPIncludeFile", tagNode->name)) + { vi = 0; - while( vi < tagNode->valuesCount ){ - if(access(tagNode->values[vi], R_OK) == -1){ + while (vi < tagNode->valuesCount) + { + if (access(tagNode->values[vi], R_OK) == -1) + { error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno)); return -1; } - if(realpath(tagNode->values[vi], realpathBuf) == NULL){ - error(tagNode->lineNum, tagNode->fileName, "realpath(%s) failed: %s", tagNode->values[vi], strerror(errno)); + + if (realpath(tagNode->values[vi], realpathBuf) == NULL) + { + error(tagNode->lineNum, tagNode->fileName, "realpath (%s) failed: %s", tagNode->values[vi], strerror(errno)); return -1; } bool processed = false; - for(std::list::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); itInode++){ - if(!strcmp(*itInode, realpathBuf)){ + for (CharList::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); ++itInode) + { + if (!strcmp(*itInode, realpathBuf)) + { processed = true; break; } } - if(processed){ + + if(processed) break; - } processedFiles.push_back(strdup(realpathBuf)); file = fopen(tagNode->values[vi], "r"); - if(file == NULL){ + if(file == NULL) + { error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno)); return -1; } fileName = strdup(realpathBuf); - from = nodeTree.end(); --from; + from = nodeTree.end(); + --from; ret = parseFile(); - (void) fclose(file); - if(ret == -1) + fclose(file); + + if (ret == -1) return -1; - if(checkConfig(++from) == -1){ + if (checkConfig(++from) == -1) return -1; - } + ++vi; } } } - - if(!requiredOptions.empty()) + if (!requiredOptions.empty()) ret = checkRequiredOptions(); } @@ -429,124 +507,150 @@ int DOTCONFDocument::setContent(const char * _fileName) int DOTCONFDocument::checkRequiredOptions() { - for(std::list::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ci++){ + for (CharList::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ++ci) + { bool matched = false; - for(std::list::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){ - if(!cmp_func((*i)->name, *ci)){ + for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i) + { + if (!cmp_func((*i)->name, *ci)) + { matched = true; break; } } - if(!matched){ + + if(!matched) + { error(0, NULL, "required option '%s' not specified", *ci); return -1; } } + return 0; } -void DOTCONFDocument::error(int lineNum, const char * fileName_, const char * fmt, ...) +void DOTCONFDocument::error(int lineNum, const char* fileName_, const char* fmt, ...) { va_list args; va_start(args, fmt); - size_t len = (lineNum!=0?strlen(fileName_):0) + strlen(fmt) + 50; - char * buf = (char*)mempool->alloc(len); + size_t len = (lineNum != 0 ? strlen(fileName_) : 0) + strlen(fmt) + 50; + char* buf = (char*)mempool->Alloc(len); - if(lineNum) - (void) snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt); + if (lineNum) + snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt); else - (void) snprintf(buf, len, "DOTCONF++: %s\n", fmt); + snprintf(buf, len, "DOTCONF++: %s\n", fmt); - (void) vfprintf(stderr, buf, args); + vfprintf(stderr, buf, args); va_end(args); } -char * DOTCONFDocument::getSubstitution(char * macro, int lineNum) +char* DOTCONFDocument::getSubstitution(char* macro, int lineNum) { - char * buf = NULL; - char * variable = macro+2; + char* buf = NULL; + char* variable = macro + 2; - char * endBr = strchr(macro, '}'); + char* endBr = strchr(macro, '}'); - if(!endBr){ + if (!endBr) + { error(lineNum, fileName, "unterminated '{'"); return NULL; } + *endBr = 0; - char * defaultValue = strchr(variable, ':'); + char* defaultValue = strchr(variable, ':'); - if(defaultValue){ + if (defaultValue) + { *defaultValue++ = 0; - if(*defaultValue != '-'){ + if (*defaultValue != '-') + { error(lineNum, fileName, "incorrect macro substitution syntax"); return NULL; } - ++defaultValue; - if(*defaultValue == '"' || *defaultValue == '\''){ - ++defaultValue; - defaultValue[strlen(defaultValue)-1] = 0; - } - } else { - defaultValue = NULL; - } - char * subs = getenv(variable); - if( subs ){ - buf = mempool->strdup(subs); - } else { - std::list::iterator i = nodeTree.begin(); - DOTCONFDocumentNode * tagNode = NULL; - for(; i!=nodeTree.end(); i++){ + ++defaultValue; + if (*defaultValue == '"' || *defaultValue == '\'') + { + ++defaultValue; + defaultValue[strlen(defaultValue) - 1] = 0; + } + } + else + defaultValue = NULL; + + char* subs = getenv(variable); + if (subs) + buf = mempool->Strdup(subs); + else + { + NodeList::iterator i = nodeTree.begin(); + DOTCONFDocumentNode* tagNode = NULL; + for (; i != nodeTree.end(); ++i) + { tagNode = *i; - if(!cmp_func(tagNode->name, variable)){ - if(tagNode->valuesCount != 0){ - buf = mempool->strdup(tagNode->values[0]); + if (!cmp_func(tagNode->name, variable)) + { + if (tagNode->valuesCount != 0) + { + buf = mempool->Strdup(tagNode->values[0]); break; } } } - if( i == nodeTree.end() ){ - if( defaultValue ){ - buf = mempool->strdup(defaultValue); - } else { + + if (i == nodeTree.end()) + { + if (defaultValue) + buf = mempool->Strdup(defaultValue); + else + { error(lineNum, fileName, "substitution not found and default value not given"); return NULL; } } } + return buf; } -int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex) +int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex) { int ret = 0; - char * macro = tagNode->values[valueIndex]; - size_t valueLen = strlen(tagNode->values[valueIndex])+1; - char * value = (char*)mempool->alloc(valueLen); - char * v = value; - char * subs = NULL; + char* macro = tagNode->values[valueIndex]; + size_t valueLen = strlen(tagNode->values[valueIndex]) + 1; + char* value = (char*)mempool->Alloc(valueLen); + char* v = value; + char* subs = NULL; - while(*macro){ - if(*macro == '$' && *(macro+1) == '{'){ - char * m = strchr(macro, '}'); + while (*macro) + { + if (*macro == '$' && *(macro + 1) == '{') + { + char* m = strchr(macro, '}'); subs = getSubstitution(macro, tagNode->lineNum); - if(subs == NULL){ + if(subs == NULL) + { ret = -1; break; } + macro = m + 1; *v = 0; - v = (char*)mempool->alloc(strlen(value)+strlen(subs)+valueLen); + v = (char*)mempool->Alloc(strlen(value) + strlen(subs) + valueLen); strcpy(v, value); value = strcat(v, subs); v = value + strlen(value); continue; } + *v++ = *macro++; } + *v = 0; free(tagNode->values[valueIndex]); @@ -554,47 +658,47 @@ int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueInd return ret; } -const DOTCONFDocumentNode * DOTCONFDocument::getFirstNode() const +const DOTCONFDocumentNode* DOTCONFDocument::getFirstNode() const { - if ( !nodeTree.empty() ) { + if (!nodeTree.empty()) return *nodeTree.begin(); - } else { + else return NULL; - } } -const DOTCONFDocumentNode * DOTCONFDocument::findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode, const DOTCONFDocumentNode * startNode) const +const DOTCONFDocumentNode* DOTCONFDocument::findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode, const DOTCONFDocumentNode* startNode) const { + NodeList::const_iterator i = nodeTree.begin(); - - std::list::const_iterator i = nodeTree.begin(); - - if(startNode == NULL) + if (startNode == NULL) startNode = parentNode; - if(startNode != NULL){ - while( i != nodeTree.end() && (*i) != startNode ){ + if (startNode != NULL) + { + while (i != nodeTree.end() && (*i) != startNode) + ++i; + + if (i != nodeTree.end()) ++i; - } - if( i != nodeTree.end() ) ++i; } - for(; i!=nodeTree.end(); i++){ - - if((*i)->parentNode != parentNode){ + for (; i != nodeTree.end(); ++i) + { + if ((*i)->parentNode != parentNode) continue; - } - if(!cmp_func(nodeName, (*i)->name)){ + + if (!cmp_func(nodeName, (*i)->name)) return *i; - } } + return NULL; } -void DOTCONFDocument::setRequiredOptionNames(const char ** requiredOptionNames) +void DOTCONFDocument::setRequiredOptionNames(const char** requiredOptionNames) { - while(*requiredOptionNames){ - requiredOptions.push_back(strdup( *requiredOptionNames )); + while (*requiredOptionNames) + { + requiredOptions.push_back(strdup(*requiredOptionNames)); ++requiredOptionNames; } } diff --git a/src/shared/Config/dotconfpp/dotconfpp.h b/src/shared/Config/dotconfpp/dotconfpp.h index 77b6fda98..55e6dd75d 100644 --- a/src/shared/Config/dotconfpp/dotconfpp.h +++ b/src/shared/Config/dotconfpp/dotconfpp.h @@ -1,6 +1,3 @@ - - - #ifndef DOTCONFPP_H #define DOTCONFPP_H @@ -21,77 +18,94 @@ class DOTCONFDocument; class DOTCONFDocumentNode { -friend class DOTCONFDocument; -private: - DOTCONFDocumentNode * previousNode; - DOTCONFDocumentNode * nextNode; - DOTCONFDocumentNode * parentNode; - DOTCONFDocumentNode * childNode; - char ** values; - int valuesCount; - char * name; - const DOTCONFDocument * document; - int lineNum; - char * fileName; - bool closed; + friend class DOTCONFDocument; - void pushValue(char * _value); + private: -public: - DOTCONFDocumentNode(); - ~DOTCONFDocumentNode(); + DOTCONFDocumentNode* previousNode; + DOTCONFDocumentNode* nextNode; + DOTCONFDocumentNode* parentNode; + DOTCONFDocumentNode* childNode; + char** values; + int valuesCount; + char* name; + const DOTCONFDocument* document; + int lineNum; + char* fileName; + bool closed; - const char * getConfigurationFileName()const { return fileName; } - int getConfigurationLineNumber() const { return lineNum; } + void pushValue(char* _value); - const DOTCONFDocumentNode * getNextNode() const { return nextNode; } - const DOTCONFDocumentNode * getPreviuosNode() const { return previousNode; } - const DOTCONFDocumentNode * getParentNode() const { return parentNode; } - const DOTCONFDocumentNode * getChildNode() const { return childNode; } - const char* getValue(int index = 0) const; - const char * getName() const { return name; } - const DOTCONFDocument * getDocument() const { return document; } + public: + + DOTCONFDocumentNode(); + ~DOTCONFDocumentNode(); + + const char* getConfigurationFileName() const { return fileName; } + int getConfigurationLineNumber() const { return lineNum; } + + const DOTCONFDocumentNode* getNextNode() const { return nextNode; } + const DOTCONFDocumentNode* getPreviuosNode() const { return previousNode; } + const DOTCONFDocumentNode* getParentNode() const { return parentNode; } + const DOTCONFDocumentNode* getChildNode() const { return childNode; } + const char* getValue(int index = 0) const; + const char* getName() const { return name; } + const DOTCONFDocument * getDocument() const { return document; } }; class DOTCONFDocument { -public: - enum CaseSensitive { CASESENSETIVE, CASEINSENSETIVE }; -protected: - AsyncDNSMemPool * mempool; -private: - DOTCONFDocumentNode * curParent; - DOTCONFDocumentNode * curPrev; - int curLine; - bool quoted; - std::list nodeTree; - std::list requiredOptions; - std::list processedFiles; - FILE * file; - char * fileName; - std::list words; - int (*cmp_func)(const char *, const char *); + public: - int checkRequiredOptions(); - int parseLine(); - int parseFile(DOTCONFDocumentNode * _parent = NULL); - int checkConfig(const std::list::iterator & from); - int cleanupLine(char * line); - char * getSubstitution(char * macro, int lineNum); - int macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex); + enum CaseSensitive + { + CASESENSITIVE, + CASEINSENSETIVE + }; -protected: - virtual void error(int lineNum, const char * fileName, const char * fmt, ...) ATTR_PRINTF(4,5); + protected: -public: - DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSETIVE); - virtual ~DOTCONFDocument(); + AsyncDNSMemPool* mempool; - int setContent(const char * _fileName); + private: - void setRequiredOptionNames(const char ** requiredOptionNames); - const DOTCONFDocumentNode * getFirstNode() const; - const DOTCONFDocumentNode * findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode = NULL, const DOTCONFDocumentNode * startNode = NULL) const; + typedef std::list CharList; + typedef std::list NodeList; + + DOTCONFDocumentNode* curParent; + DOTCONFDocumentNode* curPrev; + int curLine; + bool quoted; + NodeList nodeTree; + CharList requiredOptions; + CharList processedFiles; + FILE* file; + char* fileName; + CharList words; + int (*cmp_func)(const char*, const char*); + + int checkRequiredOptions(); + int parseLine(); + int parseFile(DOTCONFDocumentNode* _parent = NULL); + int checkConfig(const NodeList::iterator& from); + int cleanupLine(char* line); + char* getSubstitution(char* macro, int lineNum); + int macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex); + + protected: + + virtual void error(int lineNum, const char* fileName, const char* fmt, ...) ATTR_PRINTF(4,5); + + public: + + DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSITIVE); + virtual ~DOTCONFDocument(); + + int setContent(const char* _fileName); + + void setRequiredOptionNames(const char** requiredOptionNames); + const DOTCONFDocumentNode * getFirstNode() const; + const DOTCONFDocumentNode * findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode = NULL, const DOTCONFDocumentNode* startNode = NULL) const; }; #endif diff --git a/src/shared/Config/dotconfpp/mempool.cpp b/src/shared/Config/dotconfpp/mempool.cpp index cf589ffb2..45bdee24c 100644 --- a/src/shared/Config/dotconfpp/mempool.cpp +++ b/src/shared/Config/dotconfpp/mempool.cpp @@ -1,12 +1,9 @@ - - - #include "mempool.h" -AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size): - pool(NULL), pos(0), size(_size) +AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size) +: pool(NULL), pos(0), size(_size) { - pool = ::malloc(size); + pool = malloc(size); } AsyncDNSMemPool::PoolChunk::~PoolChunk() @@ -14,87 +11,96 @@ AsyncDNSMemPool::PoolChunk::~PoolChunk() ::free(pool); } -AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize): - chunks(NULL), chunksCount(0), defaultSize(_defaultSize), - poolUsage(0), poolUsageCounter(0) +AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize) +: chunks(NULL), chunksCount(0), defaultSize(_defaultSize), +poolUsage(0), poolUsageCounter(0) { } AsyncDNSMemPool::~AsyncDNSMemPool() { - for(size_t i = 0; isize - chunk->pos) >= size){ + if ((chunk->size - chunk->pos) >= size) + { chunk->pos += size; return ((char*)chunk->pool) + chunk->pos - size; } } + addNewChunk(size); - chunks[chunksCount-1]->pos = size; - return chunks[chunksCount-1]->pool; + chunks[chunksCount - 1]->pos = size; + return chunks[chunksCount - 1]->pool; } -void AsyncDNSMemPool::free() +void AsyncDNSMemPool::Free() { size_t pu = 0; size_t psz = 0; ++poolUsageCounter; - for(size_t i = 0; ipos; psz += chunks[i]->size; chunks[i]->pos = 0; } - poolUsage=(poolUsage>pu)?poolUsage:pu; - if(poolUsageCounter >= 10 && chunksCount > 1){ - psz -= chunks[chunksCount-1]->size; - if(poolUsage < psz){ + poolUsage = poolUsage > pu ? poolUsage : pu; + + if (poolUsageCounter >= 10 && chunksCount > 1) + { + psz -= chunks[chunksCount - 1]->size; + if (poolUsage < psz) + { --chunksCount; delete chunks[chunksCount]; } + poolUsage = 0; poolUsageCounter = 0; } } -void * AsyncDNSMemPool::calloc(size_t size) +void* AsyncDNSMemPool::Calloc(size_t size) { - return ::memset(this->alloc(size), 0, size); + return ::memset(Alloc(size), 0, size); } -char * AsyncDNSMemPool::strdup(const char *str) +char* AsyncDNSMemPool::Strdup(const char *str) { - return ::strcpy((char*)this->alloc(strlen(str)+1), str); + return ::strcpy((char*)Alloc(strlen(str) + 1), str); } diff --git a/src/shared/Config/dotconfpp/mempool.h b/src/shared/Config/dotconfpp/mempool.h index 04bd1e006..44b789551 100644 --- a/src/shared/Config/dotconfpp/mempool.h +++ b/src/shared/Config/dotconfpp/mempool.h @@ -1,6 +1,3 @@ - - - #ifndef ASYNC_DNS_MEMPOOL_H #define ASYNC_DNS_MEMPOOL_H @@ -8,39 +5,39 @@ #include #include -#undef free -#undef calloc -#undef strdup - class AsyncDNSMemPool { -private: - struct PoolChunk { - void * pool; - size_t pos; - size_t size; + private: - PoolChunk(size_t _size); - ~PoolChunk(); - }; - PoolChunk ** chunks; - size_t chunksCount; - size_t defaultSize; + struct PoolChunk + { + void* pool; + size_t pos; + size_t size; - size_t poolUsage; - size_t poolUsageCounter; + PoolChunk(size_t _size); + ~PoolChunk(); + }; - void addNewChunk(size_t size); + PoolChunk** chunks; + size_t chunksCount; + size_t defaultSize; -public: - AsyncDNSMemPool(size_t _defaultSize = 4096); - virtual ~AsyncDNSMemPool(); + size_t poolUsage; + size_t poolUsageCounter; - int initialize(); - void free(); - void * alloc(size_t size); - void * calloc(size_t size); - char * strdup(const char *str); + void addNewChunk(size_t size); + + public: + + AsyncDNSMemPool(size_t _defaultSize = 4096); + virtual ~AsyncDNSMemPool(); + + bool initialize(); + void Free(); + void* Alloc(size_t size); + void* Calloc(size_t size); + char* Strdup(const char *str); }; #endif diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e21c06418..1d5d1cedf 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8643" + #define REVISION_NR "8656" #endif // __REVISION_NR_H__