mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
Merge commit 'origin/master' into 330
This commit is contained in:
commit
dd9fd414bb
42 changed files with 1073 additions and 728 deletions
|
|
@ -28,8 +28,114 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Platform/Define.h"
|
#include "Platform/Define.h"
|
||||||
#include "Utilities/TypeList.h"
|
#include "Utilities/TypeList.h"
|
||||||
|
#include "Utilities/UnorderedMap.h"
|
||||||
#include "GameSystem/GridRefManager.h"
|
#include "GameSystem/GridRefManager.h"
|
||||||
|
|
||||||
|
template<class OBJECT, class KEY_TYPE> struct ContainerUnorderedMap
|
||||||
|
{
|
||||||
|
UNORDERED_MAP<KEY_TYPE, OBJECT*> _element;
|
||||||
|
};
|
||||||
|
template<class KEY_TYPE> struct ContainerUnorderedMap<TypeNull, KEY_TYPE>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template<class H, class T, class KEY_TYPE> struct ContainerUnorderedMap< TypeList<H, T>, KEY_TYPE >
|
||||||
|
{
|
||||||
|
ContainerUnorderedMap<H, KEY_TYPE> _elements;
|
||||||
|
ContainerUnorderedMap<T, KEY_TYPE> _TailElements;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class OBJECT_TYPES, class KEY_TYPE = OBJECT_HANDLE>
|
||||||
|
class TypeUnorderedMapContainer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<class SPECIFIC_TYPE> bool insert(KEY_TYPE handle, SPECIFIC_TYPE* obj)
|
||||||
|
{
|
||||||
|
return TypeUnorderedMapContainer::insert(i_elements, handle, obj);
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE> bool erase(KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return TypeUnorderedMapContainer::erase(i_elements, handle, (SPECIFIC_TYPE*)NULL);
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE> SPECIFIC_TYPE* find(KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return TypeUnorderedMapContainer::find(i_elements, hdl, (SPECIFIC_TYPE*)NULL);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> i_elements;
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
// Insert helpers
|
||||||
|
template<class SPECIFIC_TYPE> static bool insert(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE handle, SPECIFIC_TYPE* obj)
|
||||||
|
{
|
||||||
|
typename UNORDERED_MAP<OBJECT_HANDLE, SPECIFIC_TYPE*>::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<class SPECIFIC_TYPE> static bool insert(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class T> static bool insert(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class H, class T> static bool insert(ContainerUnorderedMap< TypeList<H, T>, 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<class SPECIFIC_TYPE> static SPECIFIC_TYPE* find(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
typename UNORDERED_MAP<OBJECT_HANDLE, SPECIFIC_TYPE*>::iterator i = elements._element.find(hdl);
|
||||||
|
if (i == elements._element.end())
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE> static SPECIFIC_TYPE* find(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE /*hdl*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class T> static SPECIFIC_TYPE* find(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE /*hdl*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class H, class T> static SPECIFIC_TYPE* find(ContainerUnorderedMap< TypeList<H, T>, 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<class SPECIFIC_TYPE> static bool erase(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
elements._element.erase(handle);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE> static bool erase(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class T> static bool erase(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<class SPECIFIC_TYPE, class H, class T> static bool erase(ContainerUnorderedMap< TypeList<H, T>, 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
|
* @class ContainerMapList is a mulit-type container for map elements
|
||||||
* By itself its meaningless but collaborate along with TypeContainers,
|
* By itself its meaningless but collaborate along with TypeContainers,
|
||||||
|
|
|
||||||
|
|
@ -1808,6 +1808,8 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
|
||||||
if(!criteria)
|
if(!criteria)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
assert(criteria->requiredType < ACHIEVEMENT_CRITERIA_TYPE_TOTAL && "Not updated ACHIEVEMENT_CRITERIA_TYPE_TOTAL?");
|
||||||
|
|
||||||
m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
|
m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
|
||||||
m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria);
|
m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
|
#include "MapManager.h"
|
||||||
|
|
||||||
BattleGroundAB::BattleGroundAB()
|
BattleGroundAB::BattleGroundAB()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "MapManager.h"
|
||||||
|
|
||||||
BattleGroundEY::BattleGroundEY()
|
BattleGroundEY::BattleGroundEY()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "BattleGroundMgr.h"
|
#include "BattleGroundMgr.h"
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
|
#include "MapManager.h"
|
||||||
|
|
||||||
BattleGroundWS::BattleGroundWS()
|
BattleGroundWS::BattleGroundWS()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -141,14 +141,18 @@ Creature::~Creature()
|
||||||
void Creature::AddToWorld()
|
void Creature::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the creature for guid lookup
|
///- Register the creature for guid lookup
|
||||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
if(!IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().insert<Creature>(GetGUID(), (Creature*)this);
|
||||||
|
|
||||||
Unit::AddToWorld();
|
Unit::AddToWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::RemoveFromWorld()
|
void Creature::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the creature from the accessor
|
///- Remove the creature from the accessor
|
||||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
if(IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().erase<Creature>(GetGUID(), (Creature*)NULL);
|
||||||
|
|
||||||
Unit::RemoveFromWorld();
|
Unit::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ void DynamicObject::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the dynamicObject for guid lookup
|
///- Register the dynamicObject for guid lookup
|
||||||
if(!IsInWorld())
|
if(!IsInWorld())
|
||||||
ObjectAccessor::Instance().AddObject(this);
|
GetMap()->GetObjectsStore().insert<DynamicObject>(GetGUID(), (DynamicObject*)this);
|
||||||
|
|
||||||
Object::AddToWorld();
|
Object::AddToWorld();
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ void DynamicObject::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the dynamicObject from the accessor
|
///- Remove the dynamicObject from the accessor
|
||||||
if(IsInWorld())
|
if(IsInWorld())
|
||||||
ObjectAccessor::Instance().RemoveObject(this);
|
GetMap()->GetObjectsStore().erase<DynamicObject>(GetGUID(), (DynamicObject*)NULL);
|
||||||
|
|
||||||
Object::RemoveFromWorld();
|
Object::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,23 +60,26 @@ GameObject::GameObject() : WorldObject()
|
||||||
|
|
||||||
GameObject::~GameObject()
|
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<GameObject>(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())
|
if(uint64 owner_guid = GetOwnerGUID())
|
||||||
{
|
{
|
||||||
Unit* owner = NULL;
|
if (Unit* owner = IS_PLAYER_GUID(owner_guid) ? ObjectAccessor::FindPlayer(owner_guid) : GetMap()->GetCreatureOrPet(owner_guid))
|
||||||
if(IS_PLAYER_GUID(owner_guid))
|
|
||||||
owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL);
|
|
||||||
else
|
|
||||||
owner = ObjectAccessor::GetUnit(*this,owner_guid);
|
|
||||||
|
|
||||||
if(owner)
|
|
||||||
owner->RemoveGameObject(this,false);
|
owner->RemoveGameObject(this,false);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -90,20 +93,10 @@ void GameObject::CleanupsBeforeDelete()
|
||||||
GetGUIDLow(), GetGOInfo()->id, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
|
GetGUIDLow(), GetGOInfo()->id, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetMap()->GetObjectsStore().erase<GameObject>(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();
|
Object::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -700,6 +693,10 @@ bool GameObject::isVisibleForInState(Player const* u, WorldObject const* viewPoi
|
||||||
if(!IsInWorld() || !u->IsInWorld())
|
if(!IsInWorld() || !u->IsInWorld())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// invisible at client always
|
||||||
|
if(!GetGOInfo()->displayId)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Transport always visible at this step implementation
|
// Transport always visible at this step implementation
|
||||||
if(IsTransport() && IsInMap(u))
|
if(IsTransport() && IsInMap(u))
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -559,7 +559,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
||||||
|
|
||||||
void AddToWorld();
|
void AddToWorld();
|
||||||
void RemoveFromWorld();
|
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);
|
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);
|
void Update(uint32 p_time);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
// Forward class definitions
|
// Forward class definitions
|
||||||
class Corpse;
|
class Corpse;
|
||||||
class Creature;
|
class Creature;
|
||||||
|
class Vehicle;
|
||||||
class DynamicObject;
|
class DynamicObject;
|
||||||
class GameObject;
|
class GameObject;
|
||||||
class Pet;
|
class Pet;
|
||||||
|
|
@ -57,6 +58,7 @@ class Player;
|
||||||
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
|
// 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_3(Player, Creature/*pets*/, Corpse/*resurrectable*/) AllWorldObjectTypes;
|
||||||
typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
|
typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
|
||||||
|
typedef TYPELIST_5(Creature, Pet, Vehicle, GameObject, DynamicObject) AllMapStoredObjectTypes;
|
||||||
|
|
||||||
typedef GridRefManager<Corpse> CorpseMapType;
|
typedef GridRefManager<Corpse> CorpseMapType;
|
||||||
typedef GridRefManager<Creature> CreatureMapType;
|
typedef GridRefManager<Creature> CreatureMapType;
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ struct ScriptAction
|
||||||
|
|
||||||
Map::~Map()
|
Map::~Map()
|
||||||
{
|
{
|
||||||
|
ObjectAccessor::DelinkMap(this);
|
||||||
UnloadAll(true);
|
UnloadAll(true);
|
||||||
|
|
||||||
if(!m_scriptSchedule.empty())
|
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);
|
setNGrid(NULL, idx, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ObjectAccessor::LinkMap(this);
|
||||||
|
|
||||||
//lets initialize visibility distance for map
|
//lets initialize visibility distance for map
|
||||||
Map::InitVisibilityDistance();
|
Map::InitVisibilityDistance();
|
||||||
|
|
@ -2761,19 +2763,19 @@ void Map::ScriptsProcess()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HIGHGUID_UNIT:
|
case HIGHGUID_UNIT:
|
||||||
source = HashMapHolder<Creature>::Find(step.sourceGUID);
|
source = GetCreature(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PET:
|
case HIGHGUID_PET:
|
||||||
source = HashMapHolder<Pet>::Find(step.sourceGUID);
|
source = GetPet(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_VEHICLE:
|
case HIGHGUID_VEHICLE:
|
||||||
source = HashMapHolder<Vehicle>::Find(step.sourceGUID);
|
source = GetVehicle(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PLAYER:
|
case HIGHGUID_PLAYER:
|
||||||
source = HashMapHolder<Player>::Find(step.sourceGUID);
|
source = HashMapHolder<Player>::Find(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_GAMEOBJECT:
|
case HIGHGUID_GAMEOBJECT:
|
||||||
source = HashMapHolder<GameObject>::Find(step.sourceGUID);
|
source = GetGameObject(step.sourceGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_CORPSE:
|
case HIGHGUID_CORPSE:
|
||||||
source = HashMapHolder<Corpse>::Find(step.sourceGUID);
|
source = HashMapHolder<Corpse>::Find(step.sourceGUID);
|
||||||
|
|
@ -2793,19 +2795,19 @@ void Map::ScriptsProcess()
|
||||||
switch(GUID_HIPART(step.targetGUID))
|
switch(GUID_HIPART(step.targetGUID))
|
||||||
{
|
{
|
||||||
case HIGHGUID_UNIT:
|
case HIGHGUID_UNIT:
|
||||||
target = HashMapHolder<Creature>::Find(step.targetGUID);
|
target = GetCreature(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PET:
|
case HIGHGUID_PET:
|
||||||
target = HashMapHolder<Pet>::Find(step.targetGUID);
|
target = GetPet(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_VEHICLE:
|
case HIGHGUID_VEHICLE:
|
||||||
target = HashMapHolder<Vehicle>::Find(step.targetGUID);
|
target = GetVehicle(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PLAYER: // empty GUID case also
|
case HIGHGUID_PLAYER: // empty GUID case also
|
||||||
target = HashMapHolder<Player>::Find(step.targetGUID);
|
target = HashMapHolder<Player>::Find(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_GAMEOBJECT:
|
case HIGHGUID_GAMEOBJECT:
|
||||||
target = HashMapHolder<GameObject>::Find(step.targetGUID);
|
target = GetGameObject(step.targetGUID);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_CORPSE:
|
case HIGHGUID_CORPSE:
|
||||||
target = HashMapHolder<Corpse>::Find(step.targetGUID);
|
target = HashMapHolder<Corpse>::Find(step.targetGUID);
|
||||||
|
|
@ -3381,44 +3383,35 @@ void Map::ScriptsProcess()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Creature*
|
Creature* Map::GetCreature(uint64 guid)
|
||||||
Map::GetCreature(uint64 guid)
|
|
||||||
{
|
{
|
||||||
Creature * ret = ObjectAccessor::GetObjectInWorld(guid, (Creature*)NULL);
|
return m_objectsStore.find<Creature>(guid, (Creature*)NULL);
|
||||||
if(!ret)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(ret->GetMapId() != GetId())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(ret->GetInstanceId() != GetInstanceId())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObject*
|
Vehicle* Map::GetVehicle(uint64 guid)
|
||||||
Map::GetGameObject(uint64 guid)
|
|
||||||
{
|
{
|
||||||
GameObject * ret = ObjectAccessor::GetObjectInWorld(guid, (GameObject*)NULL);
|
return m_objectsStore.find<Vehicle>(guid, (Vehicle*)NULL);
|
||||||
if(!ret)
|
|
||||||
return NULL;
|
|
||||||
if(ret->GetMapId() != GetId())
|
|
||||||
return NULL;
|
|
||||||
if(ret->GetInstanceId() != GetInstanceId())
|
|
||||||
return NULL;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicObject*
|
Pet* Map::GetPet(uint64 guid)
|
||||||
Map::GetDynamicObject(uint64 guid)
|
|
||||||
{
|
{
|
||||||
DynamicObject * ret = ObjectAccessor::GetObjectInWorld(guid, (DynamicObject*)NULL);
|
return m_objectsStore.find<Pet>(guid, (Pet*)NULL);
|
||||||
if(!ret)
|
}
|
||||||
return NULL;
|
|
||||||
if(ret->GetMapId() != GetId())
|
Unit* Map::GetCreatureOrPet(uint64 guid)
|
||||||
return NULL;
|
{
|
||||||
if(ret->GetInstanceId() != GetInstanceId())
|
if (Unit* ret = GetCreature(guid))
|
||||||
return NULL;
|
return ret;
|
||||||
return ret;
|
|
||||||
|
return GetPet(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject* Map::GetGameObject(uint64 guid)
|
||||||
|
{
|
||||||
|
return m_objectsStore.find<GameObject>(guid, (GameObject*)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicObject* Map::GetDynamicObject(uint64 guid)
|
||||||
|
{
|
||||||
|
return m_objectsStore.find<DynamicObject>(guid, (DynamicObject*)NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "GameSystem/GridRefManager.h"
|
#include "GameSystem/GridRefManager.h"
|
||||||
#include "MapRefManager.h"
|
#include "MapRefManager.h"
|
||||||
|
#include "Utilities/TypeList.h"
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
@ -420,8 +421,13 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
void RemoveFromActive(Creature* obj);
|
void RemoveFromActive(Creature* obj);
|
||||||
|
|
||||||
Creature* GetCreature(uint64 guid);
|
Creature* GetCreature(uint64 guid);
|
||||||
|
Vehicle* GetVehicle(uint64 guid);
|
||||||
|
Pet* GetPet(uint64 guid);
|
||||||
|
Unit* GetCreatureOrPet(uint64 guid);
|
||||||
GameObject* GetGameObject(uint64 guid);
|
GameObject* GetGameObject(uint64 guid);
|
||||||
DynamicObject* GetDynamicObject(uint64 guid);
|
DynamicObject* GetDynamicObject(uint64 guid);
|
||||||
|
|
||||||
|
TypeUnorderedMapContainer<AllMapStoredObjectTypes>& GetObjectsStore() { return m_objectsStore; }
|
||||||
private:
|
private:
|
||||||
void LoadMapAndVMap(int gx, int gy);
|
void LoadMapAndVMap(int gx, int gy);
|
||||||
void LoadVMap(int gx, int gy);
|
void LoadVMap(int gx, int gy);
|
||||||
|
|
@ -484,6 +490,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
typedef std::set<WorldObject*> ActiveNonPlayers;
|
typedef std::set<WorldObject*> ActiveNonPlayers;
|
||||||
ActiveNonPlayers m_activeNonPlayers;
|
ActiveNonPlayers m_activeNonPlayers;
|
||||||
ActiveNonPlayers::iterator m_activeNonPlayersIter;
|
ActiveNonPlayers::iterator m_activeNonPlayersIter;
|
||||||
|
TypeUnorderedMapContainer<AllMapStoredObjectTypes> m_objectsStore;
|
||||||
private:
|
private:
|
||||||
time_t i_gridExpiry;
|
time_t i_gridExpiry;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2
|
||||||
{
|
{
|
||||||
case TYPEID_UNIT:
|
case TYPEID_UNIT:
|
||||||
{
|
{
|
||||||
flags2 = ((Unit*)this)->isInFlight() ? (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_LEVITATING) : MOVEMENTFLAG_NONE;
|
flags2 = ((Creature*)this)->canFly() ? (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_LEVITATING) : MOVEMENTFLAG_NONE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TYPEID_PLAYER:
|
case TYPEID_PLAYER:
|
||||||
|
|
|
||||||
|
|
@ -53,16 +53,16 @@ ObjectAccessor::~ObjectAccessor()
|
||||||
Creature*
|
Creature*
|
||||||
ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)
|
ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)
|
||||||
{
|
{
|
||||||
if(IS_PLAYER_GUID(guid))
|
if(IS_PLAYER_GUID(guid) || !u.IsInWorld())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(IS_PET_GUID(guid))
|
if(IS_PET_GUID(guid))
|
||||||
return GetPet(guid);
|
return u.GetMap()->GetPet(guid);
|
||||||
|
|
||||||
if(IS_VEHICLE_GUID(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*
|
Unit*
|
||||||
|
|
@ -97,8 +97,8 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const &p, uint64 guid)
|
||||||
case HIGHGUID_PLAYER: return FindPlayer(guid);
|
case HIGHGUID_PLAYER: return FindPlayer(guid);
|
||||||
case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid);
|
case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid);
|
||||||
case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid);
|
case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid);
|
||||||
case HIGHGUID_PET: return GetPet(guid);
|
case HIGHGUID_PET: return p.GetMap()->GetPet(guid);
|
||||||
case HIGHGUID_VEHICLE: return GetVehicle(guid);
|
case HIGHGUID_VEHICLE: return p.GetMap()->GetVehicle(guid);
|
||||||
case HIGHGUID_DYNAMICOBJECT:return p.GetMap()->GetDynamicObject(guid);
|
case HIGHGUID_DYNAMICOBJECT:return p.GetMap()->GetDynamicObject(guid);
|
||||||
case HIGHGUID_TRANSPORT: return NULL;
|
case HIGHGUID_TRANSPORT: return NULL;
|
||||||
case HIGHGUID_CORPSE: return GetCorpse(p,guid);
|
case HIGHGUID_CORPSE: return GetCorpse(p,guid);
|
||||||
|
|
@ -131,11 +131,11 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, u
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_PET:
|
case HIGHGUID_PET:
|
||||||
if(typemask & TYPEMASK_UNIT)
|
if(typemask & TYPEMASK_UNIT)
|
||||||
return GetPet(guid);
|
return p.GetMap()->GetPet(guid);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_VEHICLE:
|
case HIGHGUID_VEHICLE:
|
||||||
if(typemask & TYPEMASK_UNIT)
|
if(typemask & TYPEMASK_UNIT)
|
||||||
return GetVehicle(guid);
|
return p.GetMap()->GetVehicle(guid);
|
||||||
break;
|
break;
|
||||||
case HIGHGUID_DYNAMICOBJECT:
|
case HIGHGUID_DYNAMICOBJECT:
|
||||||
if(typemask & TYPEMASK_DYNAMICOBJECT)
|
if(typemask & TYPEMASK_DYNAMICOBJECT)
|
||||||
|
|
@ -175,7 +175,7 @@ ObjectAccessor::FindPlayerByName(const char *name)
|
||||||
void
|
void
|
||||||
ObjectAccessor::SaveAllPlayers()
|
ObjectAccessor::SaveAllPlayers()
|
||||||
{
|
{
|
||||||
Guard guard(*HashMapHolder<Player*>::GetLock());
|
Guard guard(*HashMapHolder<Player>::GetLock());
|
||||||
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
|
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
|
||||||
HashMapHolder<Player>::MapType::iterator itr = m.begin();
|
HashMapHolder<Player>::MapType::iterator itr = m.begin();
|
||||||
for(; itr != m.end(); ++itr)
|
for(; itr != m.end(); ++itr)
|
||||||
|
|
@ -416,13 +416,11 @@ template <class T> ACE_Thread_Mutex HashMapHolder<T>::i_lock;
|
||||||
/// Global definitions for the hashmap storage
|
/// Global definitions for the hashmap storage
|
||||||
|
|
||||||
template class HashMapHolder<Player>;
|
template class HashMapHolder<Player>;
|
||||||
template class HashMapHolder<Pet>;
|
|
||||||
template class HashMapHolder<Vehicle>;
|
|
||||||
template class HashMapHolder<GameObject>;
|
|
||||||
template class HashMapHolder<DynamicObject>;
|
|
||||||
template class HashMapHolder<Creature>;
|
|
||||||
template class HashMapHolder<Corpse>;
|
template class HashMapHolder<Corpse>;
|
||||||
|
|
||||||
|
/// Define the static member of ObjectAccessor
|
||||||
|
std::list<Map*> ObjectAccessor::i_mapList;
|
||||||
|
|
||||||
template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);
|
template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);
|
||||||
template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/);
|
template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/);
|
||||||
template Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/);
|
template Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
class Creature;
|
class Creature;
|
||||||
class Corpse;
|
class Corpse;
|
||||||
|
|
@ -95,29 +96,9 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
return HashMapHolder<T>::Find(guid);
|
return HashMapHolder<T>::Find(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/)
|
|
||||||
{
|
|
||||||
if(!guid)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (IS_PLAYER_GUID(guid))
|
|
||||||
{
|
|
||||||
Unit * u = (Unit*)HashMapHolder<Player>::Find(guid);
|
|
||||||
if(!u || !u->IsInWorld())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return u;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_PET_GUID(guid))
|
|
||||||
return (Unit*)HashMapHolder<Pet>::Find(guid);
|
|
||||||
|
|
||||||
return (Unit*)HashMapHolder<Creature>::Find(guid);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/)
|
template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/)
|
||||||
{
|
{
|
||||||
T* obj = HashMapHolder<T>::Find(guid);
|
T* obj = GetObjectInWorld(guid, (T*)NULL);
|
||||||
if(!obj || obj->GetMapId() != mapid) return NULL;
|
if(!obj || obj->GetMapId() != mapid) return NULL;
|
||||||
|
|
||||||
CellPair p = MaNGOS::ComputeCellPair(x,y);
|
CellPair p = MaNGOS::ComputeCellPair(x,y);
|
||||||
|
|
@ -201,6 +182,9 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
|
|
||||||
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
|
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
|
||||||
|
|
||||||
|
// TODO: This methods will need lock in MT environment
|
||||||
|
static void LinkMap(Map* map) { i_mapList.push_back(map); }
|
||||||
|
static void DelinkMap(Map* map) { i_mapList.remove(map); }
|
||||||
private:
|
private:
|
||||||
struct WorldObjectChangeAccumulator
|
struct WorldObjectChangeAccumulator
|
||||||
{
|
{
|
||||||
|
|
@ -211,6 +195,24 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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 <class OBJECT> static OBJECT* FindHelper(uint64 guid)
|
||||||
|
{
|
||||||
|
OBJECT* ret = NULL;
|
||||||
|
std::list<Map*>::const_iterator i = i_mapList.begin();
|
||||||
|
while (i != i_mapList.end() && !ret)
|
||||||
|
{
|
||||||
|
ret = (*i)->GetObjectsStore().find<OBJECT>(guid, (OBJECT*)NULL);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::list<Map*> i_mapList;
|
||||||
|
|
||||||
friend struct WorldObjectChangeAccumulator;
|
friend struct WorldObjectChangeAccumulator;
|
||||||
Player2CorpsesMapType i_player2corpse;
|
Player2CorpsesMapType i_player2corpse;
|
||||||
|
|
||||||
|
|
@ -223,6 +225,52 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
LockType i_playerGuard;
|
LockType i_playerGuard;
|
||||||
LockType i_updateGuard;
|
LockType i_updateGuard;
|
||||||
LockType i_corpseGuard;
|
LockType i_corpseGuard;
|
||||||
LockType i_petGuard;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Out of class template specializations
|
||||||
|
template <> inline Creature* ObjectAccessor::GetObjectInWorld(uint64 guid, Creature* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<Creature>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline GameObject* ObjectAccessor::GetObjectInWorld(uint64 guid, GameObject* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<GameObject>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline DynamicObject* ObjectAccessor::GetObjectInWorld(uint64 guid, DynamicObject* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<DynamicObject>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline Pet* ObjectAccessor::GetObjectInWorld(uint64 guid, Pet* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<Pet>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline Vehicle* ObjectAccessor::GetObjectInWorld(uint64 guid, Vehicle* /*fake*/)
|
||||||
|
{
|
||||||
|
return FindHelper<Vehicle>(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/)
|
||||||
|
{
|
||||||
|
if(!guid)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (IS_PLAYER_GUID(guid))
|
||||||
|
{
|
||||||
|
Unit * u = (Unit*)HashMapHolder<Player>::Find(guid);
|
||||||
|
if(!u || !u->IsInWorld())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_PET_GUID(guid))
|
||||||
|
return (Unit*)GetObjectInWorld<Pet>(guid, (Pet*)NULL);
|
||||||
|
|
||||||
|
return (Unit*)GetObjectInWorld<Creature>(guid, (Creature*)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1228,11 +1228,18 @@ void ObjectMgr::LoadGameobjects()
|
||||||
|
|
||||||
if(!gInfo->displayId)
|
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);
|
switch(gInfo->type)
|
||||||
continue;
|
{
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (!sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
|
||||||
if (gInfo->displayId && !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);
|
sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have invalid displayId (%u), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -57,23 +57,24 @@ m_declinedname(NULL)
|
||||||
|
|
||||||
Pet::~Pet()
|
Pet::~Pet()
|
||||||
{
|
{
|
||||||
if(m_uint32Values) // only for fully created Object
|
|
||||||
ObjectAccessor::Instance().RemoveObject(this);
|
|
||||||
|
|
||||||
delete m_declinedname;
|
delete m_declinedname;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pet::AddToWorld()
|
void Pet::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the pet for guid lookup
|
///- Register the pet for guid lookup
|
||||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
if(!IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().insert<Pet>(GetGUID(), (Pet*)this);
|
||||||
|
|
||||||
Unit::AddToWorld();
|
Unit::AddToWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pet::RemoveFromWorld()
|
void Pet::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the pet from the accessor
|
///- Remove the pet from the accessor
|
||||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
if(IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().erase<Pet>(GetGUID(), (Pet*)NULL);
|
||||||
|
|
||||||
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
||||||
Unit::RemoveFromWorld();
|
Unit::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6106,6 +6106,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor)
|
||||||
if (uVictim != NULL)
|
if (uVictim != NULL)
|
||||||
{
|
{
|
||||||
honor *= sWorld.getRate(RATE_HONOR);
|
honor *= sWorld.getRate(RATE_HONOR);
|
||||||
|
honor *= (GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN) + 100.0f)/100.0f;
|
||||||
|
|
||||||
if(groupsize > 1)
|
if(groupsize > 1)
|
||||||
honor /= groupsize;
|
honor /= groupsize;
|
||||||
|
|
@ -13897,6 +13898,33 @@ void Player::SendCanTakeQuestResponse( uint32 msg )
|
||||||
sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID");
|
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 )
|
void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg )
|
||||||
{
|
{
|
||||||
if( pPlayer )
|
if( pPlayer )
|
||||||
|
|
@ -16536,9 +16564,13 @@ void Player::Whisper(const std::string& text, uint32 language,uint64 receiver)
|
||||||
BuildPlayerChat(&data, CHAT_MSG_WHISPER, text, language);
|
BuildPlayerChat(&data, CHAT_MSG_WHISPER, text, language);
|
||||||
rPlayer->GetSession()->SendPacket(&data);
|
rPlayer->GetSession()->SendPacket(&data);
|
||||||
|
|
||||||
data.Initialize(SMSG_MESSAGECHAT, 200);
|
// not send confirmation for addon messages
|
||||||
rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, text, language);
|
if (language != LANG_ADDON)
|
||||||
GetSession()->SendPacket(&data);
|
{
|
||||||
|
data.Initialize(SMSG_MESSAGECHAT, 200);
|
||||||
|
rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, text, language);
|
||||||
|
GetSession()->SendPacket(&data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -18789,7 +18821,7 @@ void Player::UpdateForQuestWorldObjects()
|
||||||
{
|
{
|
||||||
if(IS_GAMEOBJECT_GUID(*itr))
|
if(IS_GAMEOBJECT_GUID(*itr))
|
||||||
{
|
{
|
||||||
GameObject *obj = HashMapHolder<GameObject>::Find(*itr);
|
GameObject *obj = GetMap()->GetGameObject(*itr);
|
||||||
if(obj)
|
if(obj)
|
||||||
obj->BuildValuesUpdateBlockForPlayer(&udata,this);
|
obj->BuildValuesUpdateBlockForPlayer(&udata,this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1369,6 +1369,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void SendQuestFailed( uint32 quest_id );
|
void SendQuestFailed( uint32 quest_id );
|
||||||
void SendQuestTimerFailed( uint32 quest_id );
|
void SendQuestTimerFailed( uint32 quest_id );
|
||||||
void SendCanTakeQuestResponse( uint32 msg );
|
void SendCanTakeQuestResponse( uint32 msg );
|
||||||
|
void SendQuestConfirmAccept(Quest const* pQuest, Player* pReceiver);
|
||||||
void SendPushToPartyResponse( Player *pPlayer, uint32 msg );
|
void SendPushToPartyResponse( Player *pPlayer, uint32 msg );
|
||||||
void SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count );
|
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 );
|
void SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, uint32 creatureOrGO_idx, uint32 old_count, uint32 add_count );
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ enum __QuestFlags
|
||||||
{
|
{
|
||||||
// Flags used at server and sent to client
|
// Flags used at server and sent to client
|
||||||
QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently
|
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_EXPLORATION = 0x00000004, // Not used currently
|
||||||
QUEST_FLAGS_SHARABLE = 0x00000008, // Can be shared: Player::CanShareQuest()
|
QUEST_FLAGS_SHARABLE = 0x00000008, // Can be shared: Player::CanShareQuest()
|
||||||
//QUEST_FLAGS_NONE2 = 0x00000010, // Not used currently
|
//QUEST_FLAGS_NONE2 = 0x00000010, // Not used currently
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,30 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
_player->AddQuest( qInfo, pObject );
|
_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 ) )
|
if ( _player->CanCompleteQuest( quest ) )
|
||||||
_player->CompleteQuest( quest );
|
_player->CompleteQuest( quest );
|
||||||
|
|
||||||
|
|
@ -370,7 +394,34 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recv_data)
|
||||||
uint32 quest;
|
uint32 quest;
|
||||||
recv_data >> 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)
|
void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data)
|
||||||
|
|
|
||||||
|
|
@ -956,18 +956,31 @@ enum Mechanics
|
||||||
|
|
||||||
// Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6)
|
// Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6)
|
||||||
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \
|
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \
|
||||||
(1<<MECHANIC_CHARM )|(1<<MECHANIC_DISORIENTED )|(1<<MECHANIC_FEAR )| \
|
(1<<(MECHANIC_CHARM -1))|(1<<(MECHANIC_DISORIENTED-1))|(1<<(MECHANIC_FEAR -1))| \
|
||||||
(1<<MECHANIC_ROOT )|(1<<MECHANIC_PACIFY )|(1<<MECHANIC_SLEEP )| \
|
(1<<(MECHANIC_ROOT -1))|(1<<(MECHANIC_PACIFY -1))|(1<<(MECHANIC_SLEEP -1))| \
|
||||||
(1<<MECHANIC_SNARE )|(1<<MECHANIC_STUN )|(1<<MECHANIC_FREEZE)| \
|
(1<<(MECHANIC_SNARE -1))|(1<<(MECHANIC_STUN -1))|(1<<(MECHANIC_FREEZE-1))| \
|
||||||
(1<<MECHANIC_KNOCKOUT)|(1<<MECHANIC_POLYMORPH)|(1<<MECHANIC_BANISH)| \
|
(1<<(MECHANIC_KNOCKOUT-1))|(1<<(MECHANIC_POLYMORPH -1))|(1<<(MECHANIC_BANISH-1))| \
|
||||||
(1<<MECHANIC_SHACKLE )|(1<<MECHANIC_TURN )|(1<<MECHANIC_HORROR)| \
|
(1<<(MECHANIC_SHACKLE -1))|(1<<(MECHANIC_TURN -1))|(1<<(MECHANIC_HORROR-1))| \
|
||||||
(1<<MECHANIC_DAZE )|(1<<MECHANIC_SAPPED ) )
|
(1<<(MECHANIC_DAZE -1))|(1<<(MECHANIC_SAPPED -1)))
|
||||||
|
|
||||||
|
#define IMMUNE_TO_ROOT_AND_SNARE_MASK ( \
|
||||||
|
(1<<(MECHANIC_ROOT-1))|(1<<(MECHANIC_SNARE-1)))
|
||||||
|
|
||||||
|
#define IMMUNE_TO_ROOT_AND_STUN_MASK ( \
|
||||||
|
(1<<(MECHANIC_ROOT-1))|(1<<(MECHANIC_STUN-1)))
|
||||||
|
|
||||||
|
#define IMMUNE_TO_SILENCE_AND_STUN_AND_FEAR_MASK ( \
|
||||||
|
(1<<(MECHANIC_SILENCE-1))|(1<<(MECHANIC_STUN-1))|(1<<(MECHANIC_FEAR-1)))
|
||||||
|
|
||||||
|
#define IMMUNE_TO_INTERRUPT_AND_SILENCE_MASK ( \
|
||||||
|
(1<<(MECHANIC_INTERRUPT-1))|(1<<(MECHANIC_SILENCE-1)))
|
||||||
|
|
||||||
// Daze and all croud control spells except polymorph are not removed
|
// Daze and all croud control spells except polymorph are not removed
|
||||||
#define MECHANIC_NOT_REMOVED_BY_SHAPESHIFT ( \
|
#define MECHANIC_NOT_REMOVED_BY_SHAPESHIFT ( \
|
||||||
(1<<MECHANIC_CHARM )|(1<<MECHANIC_DISORIENTED)|(1<<MECHANIC_FEAR )|(1<<MECHANIC_PACIFY )| \
|
(1<<(MECHANIC_CHARM -1))|(1<<(MECHANIC_DISORIENTED-1))|(1<<(MECHANIC_FEAR -1))| \
|
||||||
(1<<MECHANIC_STUN )|(1<<MECHANIC_FREEZE )|(1<<MECHANIC_BANISH)|(1<<MECHANIC_SHACKLE)| \
|
(1<<(MECHANIC_PACIFY-1))|(1<<(MECHANIC_STUN -1))|(1<<(MECHANIC_FREEZE-1))| \
|
||||||
(1<<MECHANIC_HORROR)|(1<<MECHANIC_TURN )|(1<<MECHANIC_DAZE )|(1<<MECHANIC_SAPPED ) )
|
(1<<(MECHANIC_BANISH-1))|(1<<(MECHANIC_SHACKLE -1))|(1<<(MECHANIC_HORROR-1))| \
|
||||||
|
(1<<(MECHANIC_TURN -1))|(1<<(MECHANIC_DAZE -1))|(1<<(MECHANIC_SAPPED-1)))
|
||||||
|
|
||||||
// Spell dispell type
|
// Spell dispell type
|
||||||
enum DispelType
|
enum DispelType
|
||||||
|
|
|
||||||
|
|
@ -4873,15 +4873,17 @@ SpellCastResult Spell::CheckCasterAuras() const
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY)
|
if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY)
|
||||||
school_immune |= uint32(m_spellInfo->EffectMiscValue[i]);
|
school_immune |= uint32(m_spellInfo->EffectMiscValue[i]);
|
||||||
else if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY)
|
else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY)
|
||||||
mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i]);
|
mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i]-1);
|
||||||
else if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DISPEL_IMMUNITY)
|
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]));
|
dispel_immune |= GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[i]));
|
||||||
}
|
}
|
||||||
// immune movement impairment and loss of control
|
// 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;
|
mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4889,33 +4891,33 @@ SpellCastResult Spell::CheckCasterAuras() const
|
||||||
SpellCastResult prevented_reason = SPELL_CAST_OK;
|
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
|
// 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
|
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;
|
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;
|
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;
|
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;
|
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;
|
prevented_reason = SPELL_FAILED_PACIFIED;
|
||||||
|
|
||||||
// Attr must make flag drop spell totally immune from all effects
|
// 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.
|
//Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
|
||||||
Unit::AuraMap const& auras = m_caster->GetAuras();
|
Unit::AuraMap const& auras = m_caster->GetAuras();
|
||||||
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
|
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;
|
continue;
|
||||||
if( GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune )
|
if (GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune)
|
||||||
continue;
|
continue;
|
||||||
if( (1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune)
|
if ((1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Make a second check for spell failed so the right SPELL_FAILED message is returned.
|
// Make a second check for spell failed so the right SPELL_FAILED message is returned.
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ enum AuraType
|
||||||
SPELL_AURA_SAFE_FALL = 144,
|
SPELL_AURA_SAFE_FALL = 144,
|
||||||
SPELL_AURA_MOD_PET_TALENT_POINTS = 145,
|
SPELL_AURA_MOD_PET_TALENT_POINTS = 145,
|
||||||
SPELL_AURA_ALLOW_TAME_PET_TYPE = 146,
|
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_RETAIN_COMBO_POINTS = 148,
|
||||||
SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback
|
SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback
|
||||||
SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150,
|
SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150,
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
||||||
&Aura::HandleAuraSafeFall, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
|
&Aura::HandleAuraSafeFall, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
|
||||||
&Aura::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS
|
&Aura::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS
|
||||||
&Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
|
&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::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
|
||||||
&Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
|
&Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
|
||||||
&Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
|
&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, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
|
||||||
&Aura::HandleNULL, //279 visual effects? 58836 and 57507
|
&Aura::HandleNULL, //279 visual effects? 58836 and 57507
|
||||||
&Aura::HandleModTargetArmorPct, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
|
&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::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
|
||||||
&Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
|
&Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
|
||||||
&Aura::HandleUnused, //284 51 spells
|
&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 spell that caused this aura has Croud Control or Daze effect
|
||||||
if((aurMechMask & MECHANIC_NOT_REMOVED_BY_SHAPESHIFT) ||
|
if((aurMechMask & MECHANIC_NOT_REMOVED_BY_SHAPESHIFT) ||
|
||||||
// some Daze spells have these parameters instead of MECHANIC_DAZE (skip snare spells)
|
// 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;
|
++iter;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -4171,32 +4172,13 @@ void Aura::HandleModMechanicImmunity(bool apply, bool /*Real*/)
|
||||||
|
|
||||||
if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
|
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
|
//immune movement impairment and loss of control
|
||||||
if(GetId()==42292 || GetId()==59752)
|
if(GetId()==42292 || GetId()==59752)
|
||||||
mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
|
mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
|
||||||
|
|
||||||
Unit::AuraMap& Auras = m_target->GetAuras();
|
m_target->RemoveAurasAtMechanicImmunity(mechanic,GetId());
|
||||||
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->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,misc,apply);
|
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
|
//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*/)
|
void Aura::HandleAuraModEffectImmunity(bool apply, bool /*Real*/)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,7 @@ class MANGOS_DLL_SPEC Aura
|
||||||
void HandleFarSight(bool Apply, bool Real);
|
void HandleFarSight(bool Apply, bool Real);
|
||||||
void HandleModPossessPet(bool Apply, bool Real);
|
void HandleModPossessPet(bool Apply, bool Real);
|
||||||
void HandleModMechanicImmunity(bool Apply, bool Real);
|
void HandleModMechanicImmunity(bool Apply, bool Real);
|
||||||
|
void HandleModMechanicImmunityMask(bool Apply, bool Real);
|
||||||
void HandleAuraModSkill(bool Apply, bool Real);
|
void HandleAuraModSkill(bool Apply, bool Real);
|
||||||
void HandleModDamagePercentDone(bool Apply, bool Real);
|
void HandleModDamagePercentDone(bool Apply, bool Real);
|
||||||
void HandleModPercentStat(bool Apply, bool Real);
|
void HandleModPercentStat(bool Apply, bool Real);
|
||||||
|
|
|
||||||
|
|
@ -4989,26 +4989,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
||||||
if(!unitTarget)
|
if(!unitTarget)
|
||||||
return;
|
return;
|
||||||
// Removes snares and roots.
|
// Removes snares and roots.
|
||||||
uint32 mechanic_mask = (1<<MECHANIC_ROOT) | (1<<MECHANIC_SNARE);
|
unitTarget->RemoveAurasAtMechanicImmunity(IMMUNE_TO_ROOT_AND_SNARE_MASK,30918,true);
|
||||||
Unit::AuraMap& Auras = unitTarget->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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Flame Crash
|
// Flame Crash
|
||||||
|
|
|
||||||
|
|
@ -1633,6 +1633,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
|
||||||
// Beacon of Light and Light's Beacon
|
// Beacon of Light and Light's Beacon
|
||||||
if ((spellInfo_1->SpellIconID == 3032) && (spellInfo_2->SpellIconID == 3032))
|
if ((spellInfo_1->SpellIconID == 3032) && (spellInfo_2->SpellIconID == 3032))
|
||||||
return false;
|
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)
|
// Combustion and Fire Protection Aura (multi-family check)
|
||||||
|
|
@ -3309,23 +3313,33 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto
|
||||||
|
|
||||||
// Get by mechanic
|
// Get by mechanic
|
||||||
uint32 mechanic = GetAllSpellMechanicMask(spellproto);
|
uint32 mechanic = GetAllSpellMechanicMask(spellproto);
|
||||||
if (mechanic == MECHANIC_NONE) return DIMINISHING_NONE;
|
if (!mechanic)
|
||||||
if (mechanic & ((1<<MECHANIC_STUN) |
|
return DIMINISHING_NONE;
|
||||||
(1<<MECHANIC_SHACKLE))) return triggered ? DIMINISHING_TRIGGER_STUN : DIMINISHING_CONTROL_STUN;
|
|
||||||
if (mechanic & (1<<MECHANIC_SLEEP)) return DIMINISHING_FREEZE_SLEEP;
|
|
||||||
if (mechanic & (1<<MECHANIC_POLYMORPH)) return DIMINISHING_POLYMORPH_GOUGE_SAP;
|
|
||||||
if (mechanic & (1<<MECHANIC_ROOT)) return triggered ? DIMINISHING_TRIGGER_ROOT : DIMINISHING_CONTROL_ROOT;
|
|
||||||
if (mechanic & ((1<<MECHANIC_FEAR) |
|
|
||||||
(1<<MECHANIC_TURN))) return DIMINISHING_FEAR_BLIND;
|
|
||||||
if (mechanic & (1<<MECHANIC_CHARM)) return DIMINISHING_CHARM;
|
|
||||||
if (mechanic & (1<<MECHANIC_SILENCE)) return DIMINISHING_SILENCE;
|
|
||||||
if (mechanic & (1<<MECHANIC_DISARM)) return DIMINISHING_DISARM;
|
|
||||||
if (mechanic & (1<<MECHANIC_FREEZE)) return DIMINISHING_FREEZE_SLEEP;
|
|
||||||
if (mechanic & ((1<<MECHANIC_KNOCKOUT) |
|
|
||||||
(1<<MECHANIC_SAPPED))) return DIMINISHING_POLYMORPH_GOUGE_SAP;
|
|
||||||
if (mechanic & (1<<MECHANIC_BANISH)) return DIMINISHING_BANISH;
|
|
||||||
if (mechanic & (1<<MECHANIC_HORROR)) return DIMINISHING_DEATHCOIL;
|
|
||||||
|
|
||||||
|
if (mechanic & ((1<<(MECHANIC_STUN-1))|(1<<(MECHANIC_SHACKLE-1))))
|
||||||
|
return triggered ? DIMINISHING_TRIGGER_STUN : DIMINISHING_CONTROL_STUN;
|
||||||
|
if (mechanic & (1<<(MECHANIC_SLEEP-1)))
|
||||||
|
return DIMINISHING_FREEZE_SLEEP;
|
||||||
|
if (mechanic & (1<<(MECHANIC_POLYMORPH-1)))
|
||||||
|
return DIMINISHING_POLYMORPH_GOUGE_SAP;
|
||||||
|
if (mechanic & (1<<(MECHANIC_ROOT-1)))
|
||||||
|
return triggered ? DIMINISHING_TRIGGER_ROOT : DIMINISHING_CONTROL_ROOT;
|
||||||
|
if (mechanic & ((1<<(MECHANIC_FEAR-1))|(1<<(MECHANIC_TURN-1))))
|
||||||
|
return DIMINISHING_FEAR_BLIND;
|
||||||
|
if (mechanic & (1<<(MECHANIC_CHARM-1)))
|
||||||
|
return DIMINISHING_CHARM;
|
||||||
|
if (mechanic & (1<<(MECHANIC_SILENCE-1)))
|
||||||
|
return DIMINISHING_SILENCE;
|
||||||
|
if (mechanic & (1<<(MECHANIC_DISARM-1)))
|
||||||
|
return DIMINISHING_DISARM;
|
||||||
|
if (mechanic & (1<<(MECHANIC_FREEZE-1)))
|
||||||
|
return DIMINISHING_FREEZE_SLEEP;
|
||||||
|
if (mechanic & ((1<<(MECHANIC_KNOCKOUT-1))|(1<<(MECHANIC_SAPPED-1))))
|
||||||
|
return DIMINISHING_POLYMORPH_GOUGE_SAP;
|
||||||
|
if (mechanic & (1<<(MECHANIC_BANISH-1)))
|
||||||
|
return DIMINISHING_BANISH;
|
||||||
|
if (mechanic & (1<<(MECHANIC_HORROR-1)))
|
||||||
|
return DIMINISHING_DEATHCOIL;
|
||||||
|
|
||||||
return DIMINISHING_NONE;
|
return DIMINISHING_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -388,9 +388,9 @@ inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, int32 effect)
|
||||||
{
|
{
|
||||||
uint32 mask = 0;
|
uint32 mask = 0;
|
||||||
if (spellInfo->Mechanic)
|
if (spellInfo->Mechanic)
|
||||||
mask |= 1<<spellInfo->Mechanic;
|
mask |= 1 << (spellInfo->Mechanic - 1);
|
||||||
if (spellInfo->EffectMechanic[effect])
|
if (spellInfo->EffectMechanic[effect])
|
||||||
mask |= 1<<spellInfo->EffectMechanic[effect];
|
mask |= 1 << (spellInfo->EffectMechanic[effect] - 1);
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -398,10 +398,10 @@ inline uint32 GetAllSpellMechanicMask(SpellEntry const* spellInfo)
|
||||||
{
|
{
|
||||||
uint32 mask = 0;
|
uint32 mask = 0;
|
||||||
if (spellInfo->Mechanic)
|
if (spellInfo->Mechanic)
|
||||||
mask |= 1<<spellInfo->Mechanic;
|
mask |= 1 << (spellInfo->Mechanic - 1);
|
||||||
for (int i=0; i< 3; ++i)
|
for (int i=0; i< 3; ++i)
|
||||||
if (spellInfo->EffectMechanic[i])
|
if (spellInfo->EffectMechanic[i])
|
||||||
mask |= 1<<spellInfo->EffectMechanic[i];
|
mask |= 1 << (spellInfo->EffectMechanic[i]-1);
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4078,10 +4078,13 @@ void Unit::RemoveArenaAuras(bool onleave)
|
||||||
// used to remove positive visible auras in arenas
|
// used to remove positive visible auras in arenas
|
||||||
for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
|
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
|
if (!(iter->second->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_UNK21) &&
|
||||||
&& !iter->second->IsPassive() // don't remove passive auras
|
// don't remove stances, shadowform, pally/hunter 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->IsPassive() && // don't remove passive auras
|
||||||
&& (iter->second->IsPositive() != onleave)) // remove positive buffs on enter, negative buffs on leave
|
(!(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);
|
RemoveAura(iter);
|
||||||
else
|
else
|
||||||
++iter;
|
++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)
|
if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim)
|
||||||
return false;
|
return false;
|
||||||
// Need stun or root mechanic
|
// Need stun or root mechanic
|
||||||
if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_ROOT)|(1<<MECHANIC_STUN))))
|
if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_ROOT_AND_STUN_MASK))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (dummySpell->Id)
|
switch (dummySpell->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)
|
if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim)
|
||||||
return false;
|
return false;
|
||||||
// Need snare or root mechanic
|
// Need snare or root mechanic
|
||||||
if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_ROOT)|(1<<MECHANIC_SNARE))))
|
if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_ROOT_AND_SNARE_MASK))
|
||||||
return false;
|
return false;
|
||||||
triggered_spell_id = 61258;
|
triggered_spell_id = 61258;
|
||||||
target = this;
|
target = this;
|
||||||
|
|
@ -7159,7 +7162,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Need stun, fear or silence mechanic
|
// Need stun, fear or silence mechanic
|
||||||
if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_SILENCE)|(1<<MECHANIC_STUN)|(1<<MECHANIC_FEAR))))
|
if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_SILENCE_AND_STUN_AND_FEAR_MASK))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -7169,7 +7172,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
||||||
if(!procSpell)
|
if(!procSpell)
|
||||||
return false;
|
return false;
|
||||||
// Need Interrupt or Silenced mechanic
|
// Need Interrupt or Silenced mechanic
|
||||||
if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_INTERRUPT)|(1<<MECHANIC_SILENCE))))
|
if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_INTERRUPT_AND_SILENCE_MASK))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -8964,8 +8967,9 @@ int32 Unit::SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVi
|
||||||
int32 AdvertisedBenefit = 0;
|
int32 AdvertisedBenefit = 0;
|
||||||
AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING);
|
AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING);
|
||||||
for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
|
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;
|
AdvertisedBenefit += (*i)->GetModifier()->m_amount;
|
||||||
|
|
||||||
return AdvertisedBenefit;
|
return AdvertisedBenefit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -8974,13 +8978,13 @@ bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask)
|
||||||
//If m_immuneToSchool type contain this school type, IMMUNE damage.
|
//If m_immuneToSchool type contain this school type, IMMUNE damage.
|
||||||
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
|
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
|
||||||
for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
|
for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
|
||||||
if(itr->type & shoolMask)
|
if (itr->type & shoolMask)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
//If m_immuneToDamage type contain magic, IMMUNE damage.
|
//If m_immuneToDamage type contain magic, IMMUNE damage.
|
||||||
SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
|
SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
|
||||||
for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
|
for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
|
||||||
if(itr->type & shoolMask)
|
if (itr->type & shoolMask)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -8996,26 +9000,30 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
|
||||||
|
|
||||||
SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL];
|
SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL];
|
||||||
for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr)
|
for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr)
|
||||||
if(itr->type == spellInfo->Dispel)
|
if (itr->type == spellInfo->Dispel)
|
||||||
return true;
|
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)
|
!(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it)
|
||||||
{
|
{
|
||||||
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
|
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
|
||||||
for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
|
for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
|
||||||
if( !(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) &&
|
if (!(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) &&
|
||||||
(itr->type & GetSpellSchoolMask(spellInfo)) )
|
(itr->type & GetSpellSchoolMask(spellInfo)))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
|
if(uint32 mechanic = spellInfo->Mechanic)
|
||||||
for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
|
|
||||||
{
|
{
|
||||||
if(itr->type == spellInfo->Mechanic)
|
SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
|
||||||
{
|
for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
|
||||||
return true;
|
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;
|
return false;
|
||||||
|
|
@ -9027,14 +9035,19 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con
|
||||||
uint32 effect = spellInfo->Effect[index];
|
uint32 effect = spellInfo->Effect[index];
|
||||||
SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT];
|
SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT];
|
||||||
for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr)
|
for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr)
|
||||||
if(itr->type == effect)
|
if (itr->type == effect)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(uint32 mechanic = spellInfo->EffectMechanic[index])
|
if(uint32 mechanic = spellInfo->EffectMechanic[index])
|
||||||
{
|
{
|
||||||
SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
|
SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
|
||||||
for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9042,8 +9055,9 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con
|
||||||
{
|
{
|
||||||
SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE];
|
SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE];
|
||||||
for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
|
for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
|
||||||
if(itr->type == aura)
|
if (itr->type == aura)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Check for immune to application of harmful magical effects
|
// Check for immune to application of harmful magical effects
|
||||||
AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL);
|
AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL);
|
||||||
for(AuraList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter)
|
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
|
bool Unit::IsDamageToThreatSpell(SpellEntry const * spellInfo) const
|
||||||
{
|
{
|
||||||
if(!spellInfo)
|
if (!spellInfo)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 family = spellInfo->SpellFamilyName;
|
uint32 family = spellInfo->SpellFamilyName;
|
||||||
uint64 flags = spellInfo->SpellFamilyFlags;
|
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 == 6 && flags == 8192) || //Mind Blast
|
||||||
(family == 11 && flags == 1048576)) //Earth Shock
|
(family == 11 && flags == 1048576)) //Earth Shock
|
||||||
return true;
|
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)
|
uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType attType, SpellEntry const *spellProto, DamageEffectType damagetype, uint32 stack)
|
||||||
{
|
{
|
||||||
if(!pVictim)
|
if (!pVictim)
|
||||||
return pdamage;
|
return pdamage;
|
||||||
|
|
||||||
if(pdamage == 0)
|
if (pdamage == 0)
|
||||||
return pdamage;
|
return pdamage;
|
||||||
|
|
||||||
// differentiate for weapon damage based spells
|
// 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
|
// Shred also have bonus as MECHANIC_BLEED damages
|
||||||
if (spellProto && spellProto->SpellFamilyName==SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags & UI64LIT(0x00008000))
|
if (spellProto && spellProto->SpellFamilyName==SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags & UI64LIT(0x00008000))
|
||||||
mechanicMask |= (1 << MECHANIC_BLEED);
|
mechanicMask |= (1 << (MECHANIC_BLEED-1));
|
||||||
|
|
||||||
|
|
||||||
// FLAT damage bonus auras
|
// FLAT damage bonus auras
|
||||||
|
|
@ -11722,7 +11736,7 @@ void Unit::SetFeared(bool apply, uint64 const& casterGUID, uint32 spellID, uint3
|
||||||
GetMotionMaster()->Initialize();
|
GetMotionMaster()->Initialize();
|
||||||
|
|
||||||
// attack caster if can
|
// attack caster if can
|
||||||
Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL);
|
Unit* caster = Unit::GetUnit(*this, casterGUID);
|
||||||
if(caster && ((Creature*)this)->AI())
|
if(caster && ((Creature*)this)->AI())
|
||||||
((Creature*)this)->AI()->AttackedBy(caster);
|
((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)
|
void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||||
{
|
{
|
||||||
if(newPhaseMask==GetPhaseMask())
|
if(newPhaseMask==GetPhaseMask())
|
||||||
|
|
|
||||||
|
|
@ -1214,6 +1214,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void RemoveAurasDueToSpellByCancel(uint32 spellId);
|
void RemoveAurasDueToSpellByCancel(uint32 spellId);
|
||||||
void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo);
|
void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo);
|
||||||
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0);
|
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0);
|
||||||
|
void RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive = false);
|
||||||
|
|
||||||
void RemoveSpellsCausingAura(AuraType auraType);
|
void RemoveSpellsCausingAura(AuraType auraType);
|
||||||
void RemoveRankAurasDueToSpell(uint32 spellId);
|
void RemoveRankAurasDueToSpell(uint32 spellId);
|
||||||
|
|
|
||||||
|
|
@ -31,21 +31,23 @@ Vehicle::Vehicle() : Creature(), m_vehicleId(0)
|
||||||
|
|
||||||
Vehicle::~Vehicle()
|
Vehicle::~Vehicle()
|
||||||
{
|
{
|
||||||
if(m_uint32Values) // only for fully created Object
|
|
||||||
ObjectAccessor::Instance().RemoveObject(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vehicle::AddToWorld()
|
void Vehicle::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the vehicle for guid lookup
|
///- Register the vehicle for guid lookup
|
||||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
if(!IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().insert<Vehicle>(GetGUID(), (Vehicle*)this);
|
||||||
|
|
||||||
Unit::AddToWorld();
|
Unit::AddToWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vehicle::RemoveFromWorld()
|
void Vehicle::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the vehicle from the accessor
|
///- Remove the vehicle from the accessor
|
||||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
if(IsInWorld())
|
||||||
|
GetMap()->GetObjectsStore().erase<Vehicle>(GetGUID(), (Vehicle*)NULL);
|
||||||
|
|
||||||
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
||||||
Unit::RemoveFromWorld();
|
Unit::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -398,8 +398,8 @@ int Master::Run()
|
||||||
bool Master::_StartDB()
|
bool Master::_StartDB()
|
||||||
{
|
{
|
||||||
///- Get world database info from configuration file
|
///- Get world database info from configuration file
|
||||||
std::string dbstring;
|
std::string dbstring = sConfig.GetStringDefault("WorldDatabaseInfo", "");
|
||||||
if(!sConfig.GetString("WorldDatabaseInfo", &dbstring))
|
if(dbstring.empty())
|
||||||
{
|
{
|
||||||
sLog.outError("Database not specified in configuration file");
|
sLog.outError("Database not specified in configuration file");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -416,7 +416,8 @@ bool Master::_StartDB()
|
||||||
if(!WorldDatabase.CheckRequiredField("db_version",REVISION_DB_MANGOS))
|
if(!WorldDatabase.CheckRequiredField("db_version",REVISION_DB_MANGOS))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!sConfig.GetString("CharacterDatabaseInfo", &dbstring))
|
dbstring = sConfig.GetStringDefault("CharacterDatabaseInfo", "");
|
||||||
|
if(dbstring.empty())
|
||||||
{
|
{
|
||||||
sLog.outError("Character Database not specified in configuration file");
|
sLog.outError("Character Database not specified in configuration file");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -434,7 +435,8 @@ bool Master::_StartDB()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
///- Get login database info from configuration file
|
///- 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");
|
sLog.outError("Login database not specified in configuration file");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ char serviceDescription[] = "Massive Network Game Object Server";
|
||||||
int m_ServiceStatus = -1;
|
int m_ServiceStatus = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool StartDB(std::string &dbstring);
|
bool StartDB();
|
||||||
void UnhookSignals();
|
void UnhookSignals();
|
||||||
void HookSignals();
|
void HookSignals();
|
||||||
|
|
||||||
|
|
@ -187,8 +187,7 @@ extern int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
///- Initialize the database connection
|
///- Initialize the database connection
|
||||||
std::string dbstring;
|
if(!StartDB())
|
||||||
if(!StartDB(dbstring))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
///- Get the list of realms for the server
|
///- Get the list of realms for the server
|
||||||
|
|
@ -312,9 +311,10 @@ void OnSignal(int s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize connection to the database
|
/// 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");
|
sLog.outError("Database not specified");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -81,12 +81,6 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#if PLATFORM == PLATFORM_WINDOWS
|
|
||||||
#define STRCASECMP stricmp
|
|
||||||
#else
|
|
||||||
#define STRCASECMP strcasecmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -103,7 +97,6 @@
|
||||||
#include <ace/RW_Thread_Mutex.h>
|
#include <ace/RW_Thread_Mutex.h>
|
||||||
#include <ace/Thread_Mutex.h>
|
#include <ace/Thread_Mutex.h>
|
||||||
|
|
||||||
|
|
||||||
#if PLATFORM == PLATFORM_WINDOWS
|
#if PLATFORM == PLATFORM_WINDOWS
|
||||||
# define FD_SETSIZE 4096
|
# define FD_SETSIZE 4096
|
||||||
# include <ace/config-all.h>
|
# include <ace/config-all.h>
|
||||||
|
|
@ -128,9 +121,7 @@
|
||||||
#define I32FMT "%08I32X"
|
#define I32FMT "%08I32X"
|
||||||
#define I64FMT "%016I64X"
|
#define I64FMT "%016I64X"
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define atoll __atoi64
|
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
#define strdup _strdup
|
|
||||||
#define finite(X) _finite(X)
|
#define finite(X) _finite(X)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,16 @@
|
||||||
|
|
||||||
INSTANTIATE_SINGLETON_1(Config);
|
INSTANTIATE_SINGLETON_1(Config);
|
||||||
|
|
||||||
Config::Config() : mIgnoreCase(true), mConf(NULL)
|
Config::Config()
|
||||||
|
: mIgnoreCase(true), mConf(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Config::~Config()
|
Config::~Config()
|
||||||
{
|
{
|
||||||
delete mConf;
|
delete mConf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Config::SetSource(const char *file, bool ignorecase)
|
bool Config::SetSource(const char *file, bool ignorecase)
|
||||||
{
|
{
|
||||||
mIgnoreCase = ignorecase;
|
mIgnoreCase = ignorecase;
|
||||||
|
|
@ -46,7 +45,7 @@ bool Config::Reload()
|
||||||
|
|
||||||
mConf = new DOTCONFDocument(mIgnoreCase ?
|
mConf = new DOTCONFDocument(mIgnoreCase ?
|
||||||
DOTCONFDocument::CASEINSENSETIVE :
|
DOTCONFDocument::CASEINSENSETIVE :
|
||||||
DOTCONFDocument::CASESENSETIVE);
|
DOTCONFDocument::CASESENSITIVE);
|
||||||
|
|
||||||
if (mConf->setContent(mFilename.c_str()) == -1)
|
if (mConf->setContent(mFilename.c_str()) == -1)
|
||||||
{
|
{
|
||||||
|
|
@ -58,117 +57,58 @@ bool Config::Reload()
|
||||||
return true;
|
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)
|
std::string Config::GetStringDefault(const char* name, const char* def)
|
||||||
{
|
{
|
||||||
if(!mConf)
|
if (!mConf)
|
||||||
return std::string(def);
|
return std::string(def);
|
||||||
|
|
||||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||||
if(!node || !node->getValue())
|
if (!node || !node->getValue())
|
||||||
return std::string(def);
|
return std::string(def);
|
||||||
|
|
||||||
return std::string(node->getValue());
|
return std::string(node->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Config::GetBoolDefault(const char* name, bool def)
|
||||||
bool Config::GetBool(const char* name, bool *value)
|
|
||||||
{
|
{
|
||||||
if(!mConf)
|
if (!mConf)
|
||||||
return false;
|
return def;
|
||||||
|
|
||||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||||
if(!node || !node->getValue())
|
if (!node || !node->getValue())
|
||||||
return false;
|
return def;
|
||||||
|
|
||||||
const char* str = node->getValue();
|
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, "yes") == 0 || strcmp(str, "YES") == 0 ||
|
||||||
strcmp(str, "1") == 0)
|
strcmp(str, "1") == 0)
|
||||||
{
|
return true;
|
||||||
*value = true;
|
|
||||||
}
|
|
||||||
else
|
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;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32 Config::GetIntDefault(const char* name, int32 def)
|
||||||
|
{
|
||||||
|
if (!mConf)
|
||||||
|
return def;
|
||||||
|
|
||||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||||
if(!node || !node->getValue())
|
if (!node || !node->getValue())
|
||||||
return false;
|
return def;
|
||||||
|
|
||||||
*value = atoi(node->getValue());
|
return atoi(node->getValue());
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Config::GetFloat(const char* name, float *value)
|
float Config::GetFloatDefault(const char* name, float def)
|
||||||
{
|
{
|
||||||
if(!mConf)
|
if (!mConf)
|
||||||
return false;
|
return def;
|
||||||
|
|
||||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||||
if(!node || !node->getValue())
|
if (!node || !node->getValue())
|
||||||
return false;
|
return def;
|
||||||
|
|
||||||
*value = atof(node->getValue());
|
return 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);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,27 +27,22 @@ class DOTCONFDocument;
|
||||||
class MANGOS_DLL_SPEC Config
|
class MANGOS_DLL_SPEC Config
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Config();
|
Config();
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
bool SetSource(const char *file, bool ignorecase = true);
|
bool SetSource(const char *file, bool ignorecase = true);
|
||||||
bool Reload();
|
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);
|
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 GetBoolDefault(const char* name, const bool def = false);
|
||||||
|
int32 GetIntDefault(const char* name, const int32 def);
|
||||||
bool GetInt(const char* name, int *value);
|
|
||||||
int GetIntDefault(const char* name, const int def);
|
|
||||||
|
|
||||||
bool GetFloat(const char* name, float *value);
|
|
||||||
float GetFloatDefault(const char* name, const float def);
|
float GetFloatDefault(const char* name, const float def);
|
||||||
|
|
||||||
std::string GetFilename() const { return mFilename; }
|
std::string GetFilename() const { return mFilename; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string mFilename;
|
std::string mFilename;
|
||||||
bool mIgnoreCase;
|
bool mIgnoreCase;
|
||||||
DOTCONFDocument *mConf;
|
DOTCONFDocument *mConf;
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,68 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include "dotconfpp.h"
|
#include "dotconfpp.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define PATH_MAX _MAX_PATH
|
# define PATH_MAX _MAX_PATH
|
||||||
#define strcasecmp stricmp
|
# define strcasecmp stricmp
|
||||||
#define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH)
|
# define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH)
|
||||||
#include <io.h>
|
# include <io.h>
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
# include <unistd.h>
|
||||||
#include <limits.h>
|
# include <limits.h>
|
||||||
#include <stdint.h>
|
# include <stdint.h>
|
||||||
#include <strings.h>
|
# include <strings.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(R_OK)
|
#if !defined(R_OK)
|
||||||
#define R_OK 04
|
# define R_OK 04
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DOTCONFDocumentNode::DOTCONFDocumentNode():previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL),
|
DOTCONFDocumentNode::DOTCONFDocumentNode()
|
||||||
values(NULL), valuesCount(0),
|
: previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL),
|
||||||
name(NULL), lineNum(0), fileName(NULL), closed(true)
|
values(NULL), valuesCount(0), name(NULL), lineNum(0),
|
||||||
|
fileName(NULL), closed(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DOTCONFDocumentNode::~DOTCONFDocumentNode()
|
DOTCONFDocumentNode::~DOTCONFDocumentNode()
|
||||||
{
|
{
|
||||||
free(name);
|
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[i]);
|
||||||
}
|
|
||||||
free(values);
|
free(values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DOTCONFDocumentNode::pushValue(char * _value)
|
void DOTCONFDocumentNode::pushValue(char* _value)
|
||||||
{
|
{
|
||||||
++valuesCount;
|
++valuesCount;
|
||||||
values = (char**)realloc(values, valuesCount*sizeof(char*));
|
values = (char**)realloc(values, valuesCount * sizeof(char*));
|
||||||
values[valuesCount-1] = strdup(_value);
|
values[valuesCount - 1] = strdup(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* DOTCONFDocumentNode::getValue(int index) const
|
const char* DOTCONFDocumentNode::getValue(int index) const
|
||||||
{
|
{
|
||||||
if(index >= valuesCount){
|
if (index >= valuesCount)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
return values[index];
|
return values[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity):
|
DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity)
|
||||||
mempool(NULL),
|
: mempool(NULL), curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL)
|
||||||
curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL)
|
|
||||||
{
|
{
|
||||||
if(caseSensitivity == CASESENSETIVE){
|
switch (caseSensitivity)
|
||||||
cmp_func = strcmp;
|
{
|
||||||
} else {
|
case CASESENSITIVE:
|
||||||
cmp_func = strcasecmp;
|
cmp_func = strcmp;
|
||||||
|
break;
|
||||||
|
case CASEINSENSETIVE:
|
||||||
|
cmp_func = strcasecmp;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mempool = new AsyncDNSMemPool(1024);
|
mempool = new AsyncDNSMemPool(1024);
|
||||||
|
|
@ -67,195 +71,247 @@ DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity)
|
||||||
|
|
||||||
DOTCONFDocument::~DOTCONFDocument()
|
DOTCONFDocument::~DOTCONFDocument()
|
||||||
{
|
{
|
||||||
for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i != nodeTree.end(); i++){
|
for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
|
||||||
delete(*i);
|
delete(*i);
|
||||||
}
|
|
||||||
for(std::list<char*>::iterator i = requiredOptions.begin(); i != requiredOptions.end(); i++){
|
for (CharList::iterator i = requiredOptions.begin(); i != requiredOptions.end(); ++i)
|
||||||
free(*i);
|
free(*i);
|
||||||
}
|
|
||||||
for(std::list<char*>::iterator i = processedFiles.begin(); i != processedFiles.end(); i++){
|
for (CharList::iterator i = processedFiles.begin(); i != processedFiles.end(); ++i)
|
||||||
free(*i);
|
free(*i);
|
||||||
}
|
|
||||||
free(fileName);
|
free(fileName);
|
||||||
delete mempool;
|
delete mempool;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DOTCONFDocument::cleanupLine(char * line)
|
int DOTCONFDocument::cleanupLine(char* line)
|
||||||
{
|
{
|
||||||
char * start = line;
|
char* start = line;
|
||||||
char * bg = line;
|
char* bg = line;
|
||||||
bool multiline = false;
|
bool multiline = false;
|
||||||
bool concat = false;
|
bool concat = false;
|
||||||
char * word = NULL;
|
char* word = NULL;
|
||||||
|
|
||||||
if(!words.empty() && quoted)
|
if (!words.empty() && quoted)
|
||||||
concat = true;
|
concat = true;
|
||||||
|
|
||||||
while(*line){
|
while (*line)
|
||||||
if((*line == '#' || *line == ';') && !quoted){
|
{
|
||||||
|
if ((*line == '#' || *line == ';') && !quoted)
|
||||||
|
{
|
||||||
*bg = 0;
|
*bg = 0;
|
||||||
if(strlen(start)){
|
if (strlen(start))
|
||||||
|
{
|
||||||
if(concat){
|
if (concat)
|
||||||
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1);
|
{
|
||||||
|
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
|
||||||
strcpy(word, words.back());
|
strcpy(word, words.back());
|
||||||
strcat(word, start);
|
strcat(word, start);
|
||||||
words.pop_back();
|
words.pop_back();
|
||||||
concat = false;
|
concat = false;
|
||||||
} else {
|
|
||||||
word = mempool->strdup(start);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
word = mempool->Strdup(start);
|
||||||
|
|
||||||
words.push_back(word);
|
words.push_back(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(*line == '=' && !quoted){
|
|
||||||
*line = ' ';continue;
|
if (*line == '=' && !quoted)
|
||||||
|
{
|
||||||
|
*line = ' ';
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allowing \" in there causes problems with directory paths
|
// Allowing \" in there causes problems with directory paths
|
||||||
// like "C:\MaNGOS\"
|
// like "C:\MaNGOS\"
|
||||||
//if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){
|
//if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){
|
||||||
if(*line == '\\' && (*(line+1) == '\'')) {
|
if (*line == '\\' && (*(line + 1) == '\''))
|
||||||
*bg++ = *(line+1);
|
{
|
||||||
line+=2; continue;
|
*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){
|
if (*line == '\\' && *(line + 1) == 'n')
|
||||||
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1);
|
{
|
||||||
|
*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());
|
strcpy(word, words.back());
|
||||||
strcat(word, start);
|
strcat(word, start);
|
||||||
words.pop_back();
|
words.pop_back();
|
||||||
concat = false;
|
concat = false;
|
||||||
} else {
|
|
||||||
word = mempool->strdup(start);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
word = mempool->Strdup(start);
|
||||||
|
|
||||||
words.push_back(word);
|
words.push_back(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
multiline = true;
|
multiline = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(*line == '"' || *line == '\''){
|
|
||||||
quoted = !quoted;
|
|
||||||
++line; continue;
|
|
||||||
}
|
|
||||||
if(isspace((unsigned char)*line) && !quoted){
|
|
||||||
*bg++ = 0;
|
|
||||||
if(strlen(start)){
|
|
||||||
|
|
||||||
if(concat){
|
if (*line == '"' || *line == '\'')
|
||||||
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1);
|
{
|
||||||
|
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());
|
strcpy(word, words.back());
|
||||||
strcat(word, start);
|
strcat(word, start);
|
||||||
words.pop_back();
|
words.pop_back();
|
||||||
concat = false;
|
concat = false;
|
||||||
} else {
|
|
||||||
word = mempool->strdup(start);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
word = mempool->Strdup(start);
|
||||||
|
|
||||||
words.push_back(word);
|
words.push_back(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
start = bg;
|
start = bg;
|
||||||
while(isspace((unsigned char)*++line)) {}
|
while (isspace((unsigned char)*++line))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
*bg++ = *line++;
|
*bg++ = *line++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(quoted && !multiline){
|
if (quoted && !multiline)
|
||||||
|
{
|
||||||
error(curLine, fileName, "unterminated quote");
|
error(curLine, fileName, "unterminated quote");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return multiline?1:0;
|
return multiline ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DOTCONFDocument::parseLine()
|
int DOTCONFDocument::parseLine()
|
||||||
{
|
{
|
||||||
char * word = NULL;
|
char* word = NULL;
|
||||||
char * nodeName = NULL;
|
char* nodeName = NULL;
|
||||||
char * nodeValue = NULL;
|
char* nodeValue = NULL;
|
||||||
DOTCONFDocumentNode * tagNode = NULL;
|
DOTCONFDocumentNode* tagNode = NULL;
|
||||||
bool newNode = false;
|
bool newNode = false;
|
||||||
|
|
||||||
for(std::list<char*>::iterator i = words.begin(); i != words.end(); i++) {
|
for (CharList::iterator i = words.begin(); i != words.end(); ++i)
|
||||||
|
{
|
||||||
word = *i;
|
word = *i;
|
||||||
|
|
||||||
if(*word == '<'){
|
if (*word == '<')
|
||||||
newNode = true;
|
newNode = true;
|
||||||
}
|
|
||||||
|
|
||||||
if(newNode){
|
if (newNode)
|
||||||
|
{
|
||||||
nodeValue = NULL;
|
nodeValue = NULL;
|
||||||
nodeName = NULL;
|
nodeName = NULL;
|
||||||
newNode = false;
|
newNode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t wordLen = strlen(word);
|
size_t wordLen = strlen(word);
|
||||||
if(word[wordLen-1] == '>'){
|
if (word[wordLen - 1] == '>')
|
||||||
word[wordLen-1] = 0;
|
{
|
||||||
|
word[wordLen - 1] = 0;
|
||||||
newNode = true;
|
newNode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nodeName == NULL){
|
if (nodeName == NULL)
|
||||||
|
{
|
||||||
nodeName = word;
|
nodeName = word;
|
||||||
bool closed = true;
|
bool closed = true;
|
||||||
if(*nodeName == '<'){
|
if (*nodeName == '<')
|
||||||
if(*(nodeName+1) != '/'){
|
{
|
||||||
|
if (*(nodeName + 1) != '/')
|
||||||
|
{
|
||||||
++nodeName;
|
++nodeName;
|
||||||
closed = false;
|
closed = false;
|
||||||
} else {
|
}
|
||||||
nodeName+=2;
|
else
|
||||||
std::list<DOTCONFDocumentNode*>::reverse_iterator itr=nodeTree.rbegin();
|
{
|
||||||
for(; itr!=nodeTree.rend(); ++itr){
|
NodeList::reverse_iterator itr = nodeTree.rbegin();
|
||||||
if(!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed){
|
nodeName += 2;
|
||||||
|
for (; itr != nodeTree.rend(); ++itr)
|
||||||
|
{
|
||||||
|
if (!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed)
|
||||||
|
{
|
||||||
(*itr)->closed = true;
|
(*itr)->closed = true;
|
||||||
curParent = (*itr)->parentNode;
|
curParent = (*itr)->parentNode;
|
||||||
curPrev = *itr;
|
curPrev = *itr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(itr==nodeTree.rend()){
|
|
||||||
|
if(itr == nodeTree.rend())
|
||||||
|
{
|
||||||
error(curLine, fileName, "not matched closing tag </%s>", nodeName);
|
error(curLine, fileName, "not matched closing tag </%s>", nodeName);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tagNode = new DOTCONFDocumentNode;
|
tagNode = new DOTCONFDocumentNode;
|
||||||
tagNode->name = strdup(nodeName);
|
tagNode->name = strdup(nodeName);
|
||||||
tagNode->document = this;
|
tagNode->document = this;
|
||||||
tagNode->fileName = processedFiles.back();
|
tagNode->fileName = processedFiles.back();
|
||||||
tagNode->lineNum = curLine;
|
tagNode->lineNum = curLine;
|
||||||
tagNode->closed = closed;
|
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;
|
curPrev->nextNode = tagNode;
|
||||||
tagNode->previousNode = curPrev;
|
tagNode->previousNode = curPrev;
|
||||||
tagNode->parentNode = curParent;
|
tagNode->parentNode = curParent;
|
||||||
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
prev->childNode = tagNode;
|
prev->childNode = tagNode;
|
||||||
tagNode->parentNode = prev;
|
tagNode->parentNode = prev;
|
||||||
curParent = prev;
|
curParent = prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeTree.push_back(tagNode);
|
nodeTree.push_back(tagNode);
|
||||||
curPrev = tagNode;
|
curPrev = tagNode;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
nodeValue = word;
|
nodeValue = word;
|
||||||
tagNode->pushValue(nodeValue);
|
tagNode->pushValue(nodeValue);
|
||||||
}
|
}
|
||||||
|
|
@ -263,7 +319,8 @@ int DOTCONFDocument::parseLine()
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
|
|
||||||
|
int DOTCONFDocument::parseFile(DOTCONFDocumentNode* _parent)
|
||||||
{
|
{
|
||||||
char str[512];
|
char str[512];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
@ -273,27 +330,32 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
|
||||||
quoted = false;
|
quoted = false;
|
||||||
size_t slen = 0;
|
size_t slen = 0;
|
||||||
|
|
||||||
while(fgets(str, 511, file)){
|
while (fgets(str, 511, file))
|
||||||
|
{
|
||||||
++curLine;
|
++curLine;
|
||||||
slen = strlen(str);
|
slen = strlen(str);
|
||||||
if( slen >= 510 ){
|
if (slen >= 510)
|
||||||
error(curLine, fileName, "warning: line too long");
|
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';
|
if ((ret = cleanupLine(str)) == -1)
|
||||||
str[slen+1] = 0;
|
|
||||||
}
|
|
||||||
if((ret = cleanupLine(str)) == -1){
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if(ret == 0){
|
if (ret == 0)
|
||||||
if(!words.empty()){
|
{
|
||||||
|
if (!words.empty())
|
||||||
|
{
|
||||||
ret = parseLine();
|
ret = parseLine();
|
||||||
mempool->free();
|
mempool->Free();
|
||||||
words.clear();
|
words.clear();
|
||||||
if(ret == -1){
|
|
||||||
|
if(ret == -1)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -301,46 +363,51 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DOTCONFDocument::checkConfig(const std::list<DOTCONFDocumentNode*>::iterator & from)
|
int DOTCONFDocument::checkConfig(const NodeList::iterator& from)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
DOTCONFDocumentNode * tagNode = NULL;
|
DOTCONFDocumentNode* tagNode = NULL;
|
||||||
int vi = 0;
|
int vi = 0;
|
||||||
for(std::list<DOTCONFDocumentNode*>::iterator i = from; i != nodeTree.end(); i++){
|
for (NodeList::iterator i = from; i != nodeTree.end(); ++i)
|
||||||
|
{
|
||||||
tagNode = *i;
|
tagNode = *i;
|
||||||
if(!tagNode->closed){
|
if (!tagNode->closed)
|
||||||
|
{
|
||||||
error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name);
|
error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vi = 0;
|
|
||||||
while( vi < tagNode->valuesCount ){
|
|
||||||
|
|
||||||
if(strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}') ){
|
vi = 0;
|
||||||
ret = macroSubstitute(tagNode, vi );
|
while (vi < tagNode->valuesCount)
|
||||||
mempool->free();
|
{
|
||||||
if(ret == -1){
|
if (strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}'))
|
||||||
|
{
|
||||||
|
ret = macroSubstitute(tagNode, vi);
|
||||||
|
mempool->Free();
|
||||||
|
if (ret == -1)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++vi;
|
++vi;
|
||||||
}
|
}
|
||||||
if(ret == -1){
|
|
||||||
|
if (ret == -1)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DOTCONFDocument::setContent(const char * _fileName)
|
int DOTCONFDocument::setContent(const char* _fileName)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char realpathBuf[PATH_MAX];
|
char realpathBuf[PATH_MAX];
|
||||||
|
|
||||||
if(realpath(_fileName, realpathBuf) == NULL){
|
if (realpath(_fileName, realpathBuf) == NULL)
|
||||||
error(0, NULL, "realpath(%s) failed: %s", _fileName, strerror(errno));
|
{
|
||||||
|
error(0, NULL, "realpath (%s) failed: %s", _fileName, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -348,79 +415,90 @@ int DOTCONFDocument::setContent(const char * _fileName)
|
||||||
|
|
||||||
processedFiles.push_back(strdup(realpathBuf));
|
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));
|
error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try read utf8 header and skip it if exist
|
// Try read utf8 header and skip it if exist
|
||||||
uint32 utf8header = 0;
|
unsigned int utf8header = 0;
|
||||||
fgets((char*)&utf8header, 4, file); // Try read header
|
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
|
fseek(file, 0, SEEK_SET); // Reset read position
|
||||||
|
|
||||||
ret = parseFile();
|
ret = parseFile();
|
||||||
|
|
||||||
(void) fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
if(!ret){
|
if (!ret)
|
||||||
|
{
|
||||||
if( (ret = checkConfig(nodeTree.begin())) == -1){
|
if ((ret = checkConfig(nodeTree.begin())) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
std::list<DOTCONFDocumentNode*>::iterator from;
|
NodeList::iterator from;
|
||||||
DOTCONFDocumentNode * tagNode = NULL;
|
DOTCONFDocumentNode* tagNode = NULL;
|
||||||
int vi = 0;
|
int vi = 0;
|
||||||
for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){
|
for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
|
||||||
|
{
|
||||||
tagNode = *i;
|
tagNode = *i;
|
||||||
if(!cmp_func("DOTCONFPPIncludeFile", tagNode->name)){
|
if (!cmp_func("DOTCONFPPIncludeFile", tagNode->name))
|
||||||
|
{
|
||||||
vi = 0;
|
vi = 0;
|
||||||
while( vi < tagNode->valuesCount ){
|
while (vi < tagNode->valuesCount)
|
||||||
if(access(tagNode->values[vi], R_OK) == -1){
|
{
|
||||||
|
if (access(tagNode->values[vi], R_OK) == -1)
|
||||||
|
{
|
||||||
error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno));
|
error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno));
|
||||||
return -1;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool processed = false;
|
bool processed = false;
|
||||||
for(std::list<char*>::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); itInode++){
|
for (CharList::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); ++itInode)
|
||||||
if(!strcmp(*itInode, realpathBuf)){
|
{
|
||||||
|
if (!strcmp(*itInode, realpathBuf))
|
||||||
|
{
|
||||||
processed = true;
|
processed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(processed){
|
|
||||||
|
if(processed)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
processedFiles.push_back(strdup(realpathBuf));
|
processedFiles.push_back(strdup(realpathBuf));
|
||||||
|
|
||||||
file = fopen(tagNode->values[vi], "r");
|
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));
|
error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileName = strdup(realpathBuf);
|
fileName = strdup(realpathBuf);
|
||||||
from = nodeTree.end(); --from;
|
from = nodeTree.end();
|
||||||
|
--from;
|
||||||
|
|
||||||
ret = parseFile();
|
ret = parseFile();
|
||||||
(void) fclose(file);
|
fclose(file);
|
||||||
if(ret == -1)
|
|
||||||
|
if (ret == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if(checkConfig(++from) == -1){
|
if (checkConfig(++from) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
++vi;
|
++vi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!requiredOptions.empty())
|
||||||
if(!requiredOptions.empty())
|
|
||||||
ret = checkRequiredOptions();
|
ret = checkRequiredOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -429,124 +507,150 @@ int DOTCONFDocument::setContent(const char * _fileName)
|
||||||
|
|
||||||
int DOTCONFDocument::checkRequiredOptions()
|
int DOTCONFDocument::checkRequiredOptions()
|
||||||
{
|
{
|
||||||
for(std::list<char*>::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ci++){
|
for (CharList::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ++ci)
|
||||||
|
{
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
for(std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){
|
for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
|
||||||
if(!cmp_func((*i)->name, *ci)){
|
{
|
||||||
|
if (!cmp_func((*i)->name, *ci))
|
||||||
|
{
|
||||||
matched = true;
|
matched = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!matched){
|
|
||||||
|
if(!matched)
|
||||||
|
{
|
||||||
error(0, NULL, "required option '%s' not specified", *ci);
|
error(0, NULL, "required option '%s' not specified", *ci);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
||||||
size_t len = (lineNum!=0?strlen(fileName_):0) + strlen(fmt) + 50;
|
size_t len = (lineNum != 0 ? strlen(fileName_) : 0) + strlen(fmt) + 50;
|
||||||
char * buf = (char*)mempool->alloc(len);
|
char* buf = (char*)mempool->Alloc(len);
|
||||||
|
|
||||||
if(lineNum)
|
if (lineNum)
|
||||||
(void) snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt);
|
snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt);
|
||||||
else
|
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);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
char * DOTCONFDocument::getSubstitution(char * macro, int lineNum)
|
char* DOTCONFDocument::getSubstitution(char* macro, int lineNum)
|
||||||
{
|
{
|
||||||
char * buf = NULL;
|
char* buf = NULL;
|
||||||
char * variable = macro+2;
|
char* variable = macro + 2;
|
||||||
|
|
||||||
char * endBr = strchr(macro, '}');
|
char* endBr = strchr(macro, '}');
|
||||||
|
|
||||||
if(!endBr){
|
if (!endBr)
|
||||||
|
{
|
||||||
error(lineNum, fileName, "unterminated '{'");
|
error(lineNum, fileName, "unterminated '{'");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*endBr = 0;
|
*endBr = 0;
|
||||||
|
|
||||||
char * defaultValue = strchr(variable, ':');
|
char* defaultValue = strchr(variable, ':');
|
||||||
|
|
||||||
if(defaultValue){
|
if (defaultValue)
|
||||||
|
{
|
||||||
*defaultValue++ = 0;
|
*defaultValue++ = 0;
|
||||||
if(*defaultValue != '-'){
|
if (*defaultValue != '-')
|
||||||
|
{
|
||||||
error(lineNum, fileName, "incorrect macro substitution syntax");
|
error(lineNum, fileName, "incorrect macro substitution syntax");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
++defaultValue;
|
|
||||||
if(*defaultValue == '"' || *defaultValue == '\''){
|
|
||||||
++defaultValue;
|
|
||||||
defaultValue[strlen(defaultValue)-1] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
defaultValue = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * subs = getenv(variable);
|
++defaultValue;
|
||||||
if( subs ){
|
if (*defaultValue == '"' || *defaultValue == '\'')
|
||||||
buf = mempool->strdup(subs);
|
{
|
||||||
} else {
|
++defaultValue;
|
||||||
std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin();
|
defaultValue[strlen(defaultValue) - 1] = 0;
|
||||||
DOTCONFDocumentNode * tagNode = NULL;
|
}
|
||||||
for(; i!=nodeTree.end(); i++){
|
}
|
||||||
|
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;
|
tagNode = *i;
|
||||||
if(!cmp_func(tagNode->name, variable)){
|
if (!cmp_func(tagNode->name, variable))
|
||||||
if(tagNode->valuesCount != 0){
|
{
|
||||||
buf = mempool->strdup(tagNode->values[0]);
|
if (tagNode->valuesCount != 0)
|
||||||
|
{
|
||||||
|
buf = mempool->Strdup(tagNode->values[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( i == nodeTree.end() ){
|
|
||||||
if( defaultValue ){
|
if (i == nodeTree.end())
|
||||||
buf = mempool->strdup(defaultValue);
|
{
|
||||||
} else {
|
if (defaultValue)
|
||||||
|
buf = mempool->Strdup(defaultValue);
|
||||||
|
else
|
||||||
|
{
|
||||||
error(lineNum, fileName, "substitution not found and default value not given");
|
error(lineNum, fileName, "substitution not found and default value not given");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex)
|
int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char * macro = tagNode->values[valueIndex];
|
char* macro = tagNode->values[valueIndex];
|
||||||
size_t valueLen = strlen(tagNode->values[valueIndex])+1;
|
size_t valueLen = strlen(tagNode->values[valueIndex]) + 1;
|
||||||
char * value = (char*)mempool->alloc(valueLen);
|
char* value = (char*)mempool->Alloc(valueLen);
|
||||||
char * v = value;
|
char* v = value;
|
||||||
char * subs = NULL;
|
char* subs = NULL;
|
||||||
|
|
||||||
while(*macro){
|
while (*macro)
|
||||||
if(*macro == '$' && *(macro+1) == '{'){
|
{
|
||||||
char * m = strchr(macro, '}');
|
if (*macro == '$' && *(macro + 1) == '{')
|
||||||
|
{
|
||||||
|
char* m = strchr(macro, '}');
|
||||||
subs = getSubstitution(macro, tagNode->lineNum);
|
subs = getSubstitution(macro, tagNode->lineNum);
|
||||||
if(subs == NULL){
|
if(subs == NULL)
|
||||||
|
{
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro = m + 1;
|
macro = m + 1;
|
||||||
*v = 0;
|
*v = 0;
|
||||||
v = (char*)mempool->alloc(strlen(value)+strlen(subs)+valueLen);
|
v = (char*)mempool->Alloc(strlen(value) + strlen(subs) + valueLen);
|
||||||
strcpy(v, value);
|
strcpy(v, value);
|
||||||
value = strcat(v, subs);
|
value = strcat(v, subs);
|
||||||
v = value + strlen(value);
|
v = value + strlen(value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
*v++ = *macro++;
|
*v++ = *macro++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*v = 0;
|
*v = 0;
|
||||||
|
|
||||||
free(tagNode->values[valueIndex]);
|
free(tagNode->values[valueIndex]);
|
||||||
|
|
@ -554,47 +658,47 @@ int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueInd
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DOTCONFDocumentNode * DOTCONFDocument::getFirstNode() const
|
const DOTCONFDocumentNode* DOTCONFDocument::getFirstNode() const
|
||||||
{
|
{
|
||||||
if ( !nodeTree.empty() ) {
|
if (!nodeTree.empty())
|
||||||
return *nodeTree.begin();
|
return *nodeTree.begin();
|
||||||
} else {
|
else
|
||||||
return NULL;
|
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();
|
||||||
|
|
||||||
|
if (startNode == NULL)
|
||||||
std::list<DOTCONFDocumentNode*>::const_iterator i = nodeTree.begin();
|
|
||||||
|
|
||||||
if(startNode == NULL)
|
|
||||||
startNode = parentNode;
|
startNode = parentNode;
|
||||||
|
|
||||||
if(startNode != NULL){
|
if (startNode != NULL)
|
||||||
while( i != nodeTree.end() && (*i) != startNode ){
|
{
|
||||||
|
while (i != nodeTree.end() && (*i) != startNode)
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (i != nodeTree.end())
|
||||||
++i;
|
++i;
|
||||||
}
|
|
||||||
if( i != nodeTree.end() ) ++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(; i!=nodeTree.end(); i++){
|
for (; i != nodeTree.end(); ++i)
|
||||||
|
{
|
||||||
if((*i)->parentNode != parentNode){
|
if ((*i)->parentNode != parentNode)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if(!cmp_func(nodeName, (*i)->name)){
|
if (!cmp_func(nodeName, (*i)->name))
|
||||||
return *i;
|
return *i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DOTCONFDocument::setRequiredOptionNames(const char ** requiredOptionNames)
|
void DOTCONFDocument::setRequiredOptionNames(const char** requiredOptionNames)
|
||||||
{
|
{
|
||||||
while(*requiredOptionNames){
|
while (*requiredOptionNames)
|
||||||
requiredOptions.push_back(strdup( *requiredOptionNames ));
|
{
|
||||||
|
requiredOptions.push_back(strdup(*requiredOptionNames));
|
||||||
++requiredOptionNames;
|
++requiredOptionNames;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef DOTCONFPP_H
|
#ifndef DOTCONFPP_H
|
||||||
#define DOTCONFPP_H
|
#define DOTCONFPP_H
|
||||||
|
|
||||||
|
|
@ -21,77 +18,94 @@ class DOTCONFDocument;
|
||||||
|
|
||||||
class DOTCONFDocumentNode
|
class DOTCONFDocumentNode
|
||||||
{
|
{
|
||||||
friend class DOTCONFDocument;
|
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;
|
|
||||||
|
|
||||||
void pushValue(char * _value);
|
private:
|
||||||
|
|
||||||
public:
|
DOTCONFDocumentNode* previousNode;
|
||||||
DOTCONFDocumentNode();
|
DOTCONFDocumentNode* nextNode;
|
||||||
~DOTCONFDocumentNode();
|
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; }
|
void pushValue(char* _value);
|
||||||
int getConfigurationLineNumber() const { return lineNum; }
|
|
||||||
|
|
||||||
const DOTCONFDocumentNode * getNextNode() const { return nextNode; }
|
public:
|
||||||
const DOTCONFDocumentNode * getPreviuosNode() const { return previousNode; }
|
|
||||||
const DOTCONFDocumentNode * getParentNode() const { return parentNode; }
|
DOTCONFDocumentNode();
|
||||||
const DOTCONFDocumentNode * getChildNode() const { return childNode; }
|
~DOTCONFDocumentNode();
|
||||||
const char* getValue(int index = 0) const;
|
|
||||||
const char * getName() const { return name; }
|
const char* getConfigurationFileName() const { return fileName; }
|
||||||
const DOTCONFDocument * getDocument() const { return document; }
|
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
|
class DOTCONFDocument
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum CaseSensitive { CASESENSETIVE, CASEINSENSETIVE };
|
|
||||||
protected:
|
|
||||||
AsyncDNSMemPool * mempool;
|
|
||||||
private:
|
|
||||||
DOTCONFDocumentNode * curParent;
|
|
||||||
DOTCONFDocumentNode * curPrev;
|
|
||||||
int curLine;
|
|
||||||
bool quoted;
|
|
||||||
std::list<DOTCONFDocumentNode*> nodeTree;
|
|
||||||
std::list<char*> requiredOptions;
|
|
||||||
std::list<char*> processedFiles;
|
|
||||||
FILE * file;
|
|
||||||
char * fileName;
|
|
||||||
std::list<char*> words;
|
|
||||||
int (*cmp_func)(const char *, const char *);
|
|
||||||
|
|
||||||
int checkRequiredOptions();
|
enum CaseSensitive
|
||||||
int parseLine();
|
{
|
||||||
int parseFile(DOTCONFDocumentNode * _parent = NULL);
|
CASESENSITIVE,
|
||||||
int checkConfig(const std::list<DOTCONFDocumentNode*>::iterator & from);
|
CASEINSENSETIVE
|
||||||
int cleanupLine(char * line);
|
};
|
||||||
char * getSubstitution(char * macro, int lineNum);
|
|
||||||
int macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void error(int lineNum, const char * fileName, const char * fmt, ...) ATTR_PRINTF(4,5);
|
|
||||||
|
|
||||||
public:
|
AsyncDNSMemPool* mempool;
|
||||||
DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSETIVE);
|
|
||||||
virtual ~DOTCONFDocument();
|
|
||||||
|
|
||||||
int setContent(const char * _fileName);
|
private:
|
||||||
|
|
||||||
void setRequiredOptionNames(const char ** requiredOptionNames);
|
typedef std::list<char*> CharList;
|
||||||
const DOTCONFDocumentNode * getFirstNode() const;
|
typedef std::list<DOTCONFDocumentNode*> NodeList;
|
||||||
const DOTCONFDocumentNode * findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode = NULL, const DOTCONFDocumentNode * startNode = NULL) const;
|
|
||||||
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "mempool.h"
|
#include "mempool.h"
|
||||||
|
|
||||||
AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size):
|
AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size)
|
||||||
pool(NULL), pos(0), size(_size)
|
: pool(NULL), pos(0), size(_size)
|
||||||
{
|
{
|
||||||
pool = ::malloc(size);
|
pool = malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncDNSMemPool::PoolChunk::~PoolChunk()
|
AsyncDNSMemPool::PoolChunk::~PoolChunk()
|
||||||
|
|
@ -14,87 +11,96 @@ AsyncDNSMemPool::PoolChunk::~PoolChunk()
|
||||||
::free(pool);
|
::free(pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize):
|
AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize)
|
||||||
chunks(NULL), chunksCount(0), defaultSize(_defaultSize),
|
: chunks(NULL), chunksCount(0), defaultSize(_defaultSize),
|
||||||
poolUsage(0), poolUsageCounter(0)
|
poolUsage(0), poolUsageCounter(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncDNSMemPool::~AsyncDNSMemPool()
|
AsyncDNSMemPool::~AsyncDNSMemPool()
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i<chunksCount; i++){
|
for (size_t i = 0; i < chunksCount; ++i)
|
||||||
delete chunks[i];
|
delete chunks[i];
|
||||||
}
|
|
||||||
::free(chunks);
|
::free(chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AsyncDNSMemPool::initialize()
|
bool AsyncDNSMemPool::initialize()
|
||||||
{
|
{
|
||||||
chunksCount = 1;
|
chunksCount = 1;
|
||||||
chunks = (PoolChunk**)::malloc(sizeof(PoolChunk*));
|
chunks = (PoolChunk**)malloc(sizeof(PoolChunk*));
|
||||||
if(chunks == NULL)
|
if (chunks == NULL)
|
||||||
return -1;
|
return false;
|
||||||
|
|
||||||
chunks[chunksCount-1] = new PoolChunk(defaultSize);
|
chunks[chunksCount - 1] = new PoolChunk(defaultSize);
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncDNSMemPool::addNewChunk(size_t size)
|
void AsyncDNSMemPool::addNewChunk(size_t size)
|
||||||
{
|
{
|
||||||
++chunksCount;
|
++chunksCount;
|
||||||
chunks = (PoolChunk**)::realloc(chunks, chunksCount*sizeof(PoolChunk*));
|
|
||||||
if(size <= defaultSize)
|
chunks = (PoolChunk**)realloc(chunks, chunksCount * sizeof(PoolChunk*));
|
||||||
chunks[chunksCount-1] = new PoolChunk(defaultSize);
|
if (size <= defaultSize)
|
||||||
|
chunks[chunksCount - 1] = new PoolChunk(defaultSize);
|
||||||
else
|
else
|
||||||
chunks[chunksCount-1] = new PoolChunk(size);
|
chunks[chunksCount - 1] = new PoolChunk(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * AsyncDNSMemPool::alloc(size_t size)
|
void* AsyncDNSMemPool::Alloc(size_t size)
|
||||||
{
|
{
|
||||||
PoolChunk * chunk = NULL;
|
PoolChunk* chunk = NULL;
|
||||||
for(size_t i = 0; i<chunksCount; i++){
|
for (size_t i = 0; i < chunksCount; ++i)
|
||||||
|
{
|
||||||
chunk = chunks[i];
|
chunk = chunks[i];
|
||||||
if((chunk->size - chunk->pos) >= size){
|
if ((chunk->size - chunk->pos) >= size)
|
||||||
|
{
|
||||||
chunk->pos += size;
|
chunk->pos += size;
|
||||||
return ((char*)chunk->pool) + chunk->pos - size;
|
return ((char*)chunk->pool) + chunk->pos - size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addNewChunk(size);
|
addNewChunk(size);
|
||||||
chunks[chunksCount-1]->pos = size;
|
chunks[chunksCount - 1]->pos = size;
|
||||||
return chunks[chunksCount-1]->pool;
|
return chunks[chunksCount - 1]->pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncDNSMemPool::free()
|
void AsyncDNSMemPool::Free()
|
||||||
{
|
{
|
||||||
size_t pu = 0;
|
size_t pu = 0;
|
||||||
size_t psz = 0;
|
size_t psz = 0;
|
||||||
++poolUsageCounter;
|
++poolUsageCounter;
|
||||||
|
|
||||||
for(size_t i = 0; i<chunksCount; i++){
|
for (size_t i = 0; i < chunksCount; ++i)
|
||||||
|
{
|
||||||
pu += chunks[i]->pos;
|
pu += chunks[i]->pos;
|
||||||
psz += chunks[i]->size;
|
psz += chunks[i]->size;
|
||||||
chunks[i]->pos = 0;
|
chunks[i]->pos = 0;
|
||||||
}
|
}
|
||||||
poolUsage=(poolUsage>pu)?poolUsage:pu;
|
|
||||||
|
|
||||||
if(poolUsageCounter >= 10 && chunksCount > 1){
|
poolUsage = poolUsage > pu ? poolUsage : pu;
|
||||||
psz -= chunks[chunksCount-1]->size;
|
|
||||||
if(poolUsage < psz){
|
if (poolUsageCounter >= 10 && chunksCount > 1)
|
||||||
|
{
|
||||||
|
psz -= chunks[chunksCount - 1]->size;
|
||||||
|
if (poolUsage < psz)
|
||||||
|
{
|
||||||
--chunksCount;
|
--chunksCount;
|
||||||
delete chunks[chunksCount];
|
delete chunks[chunksCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
poolUsage = 0;
|
poolUsage = 0;
|
||||||
poolUsageCounter = 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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASYNC_DNS_MEMPOOL_H
|
#ifndef ASYNC_DNS_MEMPOOL_H
|
||||||
#define ASYNC_DNS_MEMPOOL_H
|
#define ASYNC_DNS_MEMPOOL_H
|
||||||
|
|
||||||
|
|
@ -8,39 +5,39 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#undef free
|
|
||||||
#undef calloc
|
|
||||||
#undef strdup
|
|
||||||
|
|
||||||
class AsyncDNSMemPool
|
class AsyncDNSMemPool
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
struct PoolChunk {
|
|
||||||
void * pool;
|
|
||||||
size_t pos;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
PoolChunk(size_t _size);
|
struct PoolChunk
|
||||||
~PoolChunk();
|
{
|
||||||
};
|
void* pool;
|
||||||
PoolChunk ** chunks;
|
size_t pos;
|
||||||
size_t chunksCount;
|
size_t size;
|
||||||
size_t defaultSize;
|
|
||||||
|
|
||||||
size_t poolUsage;
|
PoolChunk(size_t _size);
|
||||||
size_t poolUsageCounter;
|
~PoolChunk();
|
||||||
|
};
|
||||||
|
|
||||||
void addNewChunk(size_t size);
|
PoolChunk** chunks;
|
||||||
|
size_t chunksCount;
|
||||||
|
size_t defaultSize;
|
||||||
|
|
||||||
public:
|
size_t poolUsage;
|
||||||
AsyncDNSMemPool(size_t _defaultSize = 4096);
|
size_t poolUsageCounter;
|
||||||
virtual ~AsyncDNSMemPool();
|
|
||||||
|
|
||||||
int initialize();
|
void addNewChunk(size_t size);
|
||||||
void free();
|
|
||||||
void * alloc(size_t size);
|
public:
|
||||||
void * calloc(size_t size);
|
|
||||||
char * strdup(const char *str);
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8643"
|
#define REVISION_NR "8656"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue